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