multithreaded tcp echo server problem & flips

David Silcott lava_patch at
Tue Aug 1 13:55:53 CEST 2006

hello all,

I've ported my multithreaded tcp server to L4 using
flips but I am having some problems getting it to run
properly. It is a quite a bit to explain so I've
written a simple tcp echoserver to demonstrate my
The following happens when the server starts and the
client connects and send data.

1. Echoserver starts and listens on port 2222
2. client connects, server creates a child_server
thread to service client and starts listening again
3. client sends string to child_server thread which is
received. child_server however is unable to complete
send(echo), it seems to be blocked at this point.
4. The send is only completed when another client
attempts a connect(..and the server moves on from the
accept(..) statement).

I have appended my code at the bottom of this mail
maybe someone can spot my mistake and highlight it.

To check if I've used the threads properly I also
wrote a program in which each thread prints the
numbers from 0 to 9 and that runs fine. So I am
pointing my finger and the recv(), accept() and send()
functions in my echo server :-|

Any suggestions will be greatly appreciated.



#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>

/*** L4 INCLUDES ***/
#include <l4/names/libnames.h>
#include <l4/thread/thread.h>
#include <l4/log/l4log.h>
#include <l4/dm_mem/dm_mem.h>

#define BUF_SIZE 100

l4_threadid_t srv;
char LOG_tag[9] = "tcpecho";
int data_key;

struct th_data{
	int c;            //socket
	char foo[10];     //....

/* exit handler */
void child_exit(l4thread_t thread, void * data);
void child_exit(l4thread_t thread, void * data){
  struct th_data *ptr = (struct th_data *)data;

  /* close the connection and free up memory used by
data structure*/

/* declare exit function descriptor */

void child_server(void *data);
void child_server(void *data){
	char databuf[BUF_SIZE];
	struct th_data *dptr = (struct th_data *)data;
  int ret, sock, n;
	void *ret_val;
	l4thread_t id;
	sock = dptr->c;
	LOG("got socket\n");
	  /* register exit function */
  ret = l4thread_on_exit(&exit_fn,           // exit
function descriptor
                        data                // data
  if (ret < 0){
    /* register error function failed */
    LOG_Error("Register error function failed\n");
	id = l4thread_myself();
	LOG("Server thread starting with id %u\n",id);
  /* we are up */
  if (l4thread_started(ret_val) < 0){
      /* startup notification failed */
    LOG_Error("Startup notification failed\n");
	LOG("Entering loop to wait for requests on socket
%d.... \n",sock);
  while (1){
		LOG("At top of while loop\n");
    if((n = recv(sock, databuf, BUF_SIZE-1, 0)<=0)){
      LOG_Error("recv failed %d returned \n",n);
		databuf[4] = '\0';
		databuf[5] = '\n';
		LOG(">%s; sending ....\n",databuf);
		databuf[0] = 'X';
	/* Call on exit function to terminate */

/* Start the server */
int main(int argc, char *argv[]){

	int  c, s,err, ret_val, errcount=0;
	struct sockaddr_in addr;

	if ((argc < 2) || strcmp("--nowait", argv[1]))
		while (names_waitfor_name("ifconfig", &srv, 30000)
== 0) {
			LOG("Client(main): \"mini_ifconfig\" not available,
keep trying...");

	memset(&addr, 0, sizeof(addr));
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	addr.sin_family = AF_INET;
	addr.sin_port = htons(2222);
	LOG("try to open socket");
	if ((s=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) <
0) {
		LOG("Couldn't create socket");
		return -1;
	if (bind(s, (struct sockaddr *)&addr, sizeof(struct
sockaddr)) < 0) {
		LOG("Couldn't bind");
		return -1;
	LOG("bound to socket %d, call listen",s);
	if ((err=listen(s, 1)) < 0) {
		LOG("listen(%d): %d", s, err);
		return -1;

	LOG("echo server is up and accepting...");

		struct sockaddr dummyaddr;
		int  addrlen;
		l4thread_t th;
		struct th_data *th_dptr;
		LOG("waiting for another connection\n");
		if ((c=accept(s, &dummyaddr, &addrlen)) < 0) {
			LOG("accept(%d): %d", s, c);
			if (++errcount > 10) {
				LOG("maximum error count reached---giving up...");
		LOG("Allocating thread data struct\n");
		th_dptr = (struct th_data*)l4dm_mem_allocate(
sizeof(struct th_data), L4DM_CONTIGUOUS);
		memset(th_dptr,0,sizeof(struct th_data));
		th_dptr->c = c;
		LOG("Got a connection request, creating thread to
handle client on socket %d\n", c);		
		th = l4thread_create( child_server ,(void *)th_dptr
		ret_val = l4thread_startup_return(th);
		/* Thread started ... listening for other requests
		LOG("thread created ... listening again\n");
	return 0;

Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 

More information about the l4-hackers mailing list