This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
Re: TCP close(...) action
- From: Matt Jerdonek <maj1224 at yahoo dot com>
- To: Gary Thomas <gary at mlbassoc dot com>
- Cc: Discussion eCos <ecos-discuss at sources dot redhat dot com>
- Date: Mon, 20 Oct 2003 08:25:43 -0700 (PDT)
- Subject: Re: [ECOS] TCP close(...) action
Gary,
I can't send the actual code, so I put together this
program. I verified this program exhibits the same
behavior as I initially described.
In addition, I put some comments in the code regarding
the f_ucount. This is a member of the cyg_file
structure which is associated with each socket. Once
the f_ucount reaches 0, the FIN will be sent on the
ethernet.
#include <cyg/kernel/kapi.h>
#include <assert.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <network.h>
#include <cyg/posix/pthread.h>
#include <unistd.h>
#define STACK_SIZE 0x4000
unsigned char Stack[STACK_SIZE];
pthread_t ThreadHandle;
int sockfd;
void RecvThread(void);
int main(void)
{
pthread_attr_t ThreadAttrib;
init_all_network_interfaces();
// Create thread to make TCP connection
pthread_attr_init(&ThreadAttrib);
pthread_attr_setstackaddr(&ThreadAttrib,
&Stack[STACK_SIZE]);
pthread_attr_setstacksize(&ThreadAttrib,
STACK_SIZE);
pthread_create(&ThreadHandle, &ThreadAttrib,
(void *)RecvThread,
(void *)NULL);
// Give the thread plenty of time to connect
sleep(15);
// Workaround ...
// ... call cyg_thread_release() here ...
// ... on the RecvThread
// Close the socket
printf("Closing socket\n");
close(sockfd);
// The close will decrement the f_ucount ...
// ... from 2 to 1, but the FIN will not ...
// ... be sent until the recv is released.
// ... See function fp_ucount_dec( ) ...
// ... in io/fileio/ver/src/fd.cxx
sleep(10);
return(0);
}
void RecvThread(void)
{
// Create socket and connect to host
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd > 0)
{
struct sockaddr RmtHost;
struct sockaddr_in *pRmtHost =
(struct sockaddr_in *)&RmtHost;
// At this point the cyg_file ..
// ... structure that describes ...
// ... the sockfd ...
// ... as a f_ucount = 1
// Setup connect
memset( &RmtHost, 0,
sizeof(struct sockaddr) );
pRmtHost->sin_len =
sizeof( struct sockaddr_in );
pRmtHost->sin_family = AF_INET;
pRmtHost->sin_port = htons(4096);
pRmtHost->sin_addr.s_addr =
htonl(0xc8640196);
// Connected to the host
if (connect(sockfd, &RmtHost,
sizeof(struct sockaddr)) >= 0)
{
unsigned char RxBuffer[100];
printf("Socket connected\n");
// Will block indefinitely ...
// ... since no data will ...
// ... be received
recv(sockfd, &RxBuffer[0],
1, 0);
// Inside the recv, ...
// ... the f_ucount is now 2
printf("Recv woke\n");
}
}
}
--- Gary Thomas <gary@mlbassoc.com> wrote:
> On Sat, 2003-10-18 at 12:24, Matt Jerdonek wrote:
> > Hi Folks,
> >
> > I have a simple program with two threads that send
> /
> > recv from a single TCP socket. One thread blocks
> on a
> > recv call while the other thread sends data on the
> > same socket.
> >
> > I put a close call in the send thread. The
> expected
> > behavior was for the recv thread to wake (with 0
> bytes
> > of data) and a FIN to be sent on the ethernet.
> The
> > actual behavior was that the recv thread never
> woke
> > and the FIN was not sent. (Is this intended or a
> > bug?). I found the soclose function would not be
> > invoked because the recv was still using the file
> > handle. Once the recv released the file handle,
> the
> > FIN flowed on the ethernet.
> >
> > I worked around this issue by calling
> > cyg_thread_release from my application, which woke
> up
> > the recv thread. But I wonder if there is better
> > solution? Could (or should) the close call be
> made to
> > wake up blocked threads? If so, any suggestions?
> >
>
> How did you create this socket? How did you set up
> the send and receive threads? Maybe a code snippet
> would
> help us understand your problem.
>
> --
> Gary Thomas <gary@mlbassoc.com>
> MLB Associates
>
>
> --
> Before posting, please read the FAQ:
> http://sources.redhat.com/fom/ecos
> and search the list archive:
> http://sources.redhat.com/ml/ecos-discuss
>
__________________________________
Do you Yahoo!?
The New Yahoo! Shopping - with improved product search
http://shopping.yahoo.com
--
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss