libevent and pre-forked server ...

Sergey S. Ropchan fenix at ramb.com.ua
Mon Aug 8 14:50:46 GMT 2005


Hi All

I'm trying to create pre-forked server and trying to use libevent for 
accepting connections per worker process. Source code below. In result, 
only one forked process (worker) accept connection ! What i'm doing 
wrong !? Thanks.

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <sys/time.h>
#include <event.h>

#include <errno.h>
#include <err.h>

#define PORT 12000
#define MAXCONN 1024

#define MAXWORKERS 3
#define WORKER_TIMEOUT 1

void handle_connection(const int lsd, short event, void *ev);
void make_worker(const int lsd);

int main(void)
{
        int workers;
        int lsd, reuse = 1;
        struct sockaddr_in sa;
        pid_t pid;

        bzero(&sa, sizeof(sa));

        if ((lsd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
                errx(1, "socket: %s (%d)\n", strerror(errno), errno);

        if (setsockopt(lsd, SOL_SOCKET, SO_REUSEADDR, &reuse, 
sizeof(reuse)) < 0)
                errx(2, "setsockopt: %s (%d)\n", strerror(errno), errno);

        sa.sin_family = AF_INET;
        sa.sin_port = htons(PORT);
        sa.sin_addr.s_addr = htonl(INADDR_ANY);

        if (bind(lsd, (struct sockaddr *)&sa, sizeof(sa)) < 0)
                errx(3, "bind: %s (%d)\n", strerror(errno), errno);

        if (listen(lsd, MAXCONN) < 0)
                errx(4, "listen: %s (%d)\n", strerror(errno), errno);

        (void)fprintf(stderr, "Server is ready to accept clients\n");

        workers = 0;

        for (;;)
        {
                if (workers < MAXWORKERS)
                {

                        if((pid=fork()) == 0)
                        {
                                (void)fprintf(stderr, "Worker [%d] 
created\n", getpid());
                                make_worker(lsd);
                        }
                        else if ( pid > 0)
                                workers++;
                        else
                                errx(6, "fork: %s(%d)\n", 
strerror(errno), errno);
                }
                else
                        sleep(WORKER_TIMEOUT);         
        }

        return 0;
}



void make_worker(const int lsd)
{
        struct event ev;

        bzero(&ev, sizeof(ev));

        event_init();

        event_set(&ev, lsd, EV_READ | EV_PERSIST, handle_connection, &ev);

        if(event_add(&ev, NULL) < 0)
                errx(5, "event_add: %s (%d)\n", strerror(errno), errno);

        event_dispatch();

        (void)fprintf(stderr, "aborted\n");
}



void handle_connection(const int lsd, short event, void *ev)
{
        struct sockaddr_in remote;
        int asd = 0, socklen = 0, flags = 0;

        pid_t pid = getpid();

        socklen = sizeof(remote);
        bzero(&remote, socklen);

        event_add(ev, NULL);

        asd = accept(lsd, (struct sockaddr *)&remote, &socklen);

        if (asd > 0)
        {
                (void)fprintf(stderr, "#worker[%d]: received connection 
from: %s:%d, socket: %d\n",
                        pid, inet_ntoa(remote.sin_addr), 
ntohs(remote.sin_port), asd);

        }
        else
                errx(6, "accept: %s (%d)\n", strerror(errno), errno);
}




More information about the freebsd-hackers mailing list