Hi guys,
I'm doing some tests with broadcasting a message to several http
clients, implemented with libevent. I'm currently with a segfault,
that is demonstrated by the attached source code, that happens when
you broadcast several messages to the connected clients.
The steps to reproduce the segfault are:
1. compile the attached code: gcc test1.c -o test1 -Wall -levent
2. run it
3. access by a browser the URL: http://127.0.0.1:8000/test/1
4. press enter on the terminal running test1
5. at least here, i get a segfault :)
I'm using libevent-1.4.9-stable, compiled by myself with debug enabled.
Am I doing something wrong? Is this a bug?
Thanks in advance.
#include <sys/types.h>
#include <sys/time.h>
#include <sys/queue.h>
#include <stdlib.h>
#include <err.h>
#include <event.h>
#include <evhttp.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
#define BUFSIZE 1024
#define MAXUSERS (17*65536) // C1024K
struct evhttp_request *clients[MAXUSERS];
int slots[MAXUSERS];
void
cleanup (struct evhttp_connection *evcon, void *arg) {
int *uidp = (int *) arg;
fprintf (stderr, "disconnected uid %d\n", *uidp + 1);
clients[*uidp - 1] = NULL;
}
void
request_handler (struct evhttp_request *req, void *arg) {
struct evbuffer *buf;
buf = evbuffer_new ();
if (buf == NULL) {
err (1, "failed to create response buffer");
}
evhttp_add_header (req->output_headers, "Content-Type", "text/html; charset=utf-8");
int uid = -1;
if (strncmp (evhttp_request_uri (req), "/test/", 6) == 0) {
uid = atoi (6 + evhttp_request_uri (req));
}
if (uid <= 0) {
evbuffer_add_printf (buf, "User id not found, try /test/123 instead");
evhttp_send_reply (req, HTTP_NOTFOUND, "Not Found", buf);
evbuffer_free (buf);
return;
}
if (uid > MAXUSERS) {
evbuffer_add_printf (buf, "Max uid allowed is %d", MAXUSERS);
evhttp_send_reply (req, HTTP_SERVUNAVAIL, "We ran out of numbers", buf);
evbuffer_free (buf);
return;
}
evhttp_send_reply_start (req, HTTP_OK, "OK");
evbuffer_add_printf (buf, "Welcome, Url: â%sâ Id: %d\n", evhttp_request_uri (req), uid);
evhttp_send_reply_chunk (req, buf);
evbuffer_free (buf);
clients[uid - 1] = req;
evhttp_connection_set_closecb (req->evcon, cleanup, &slots[uid - 1]);
}
void
run () {
struct evbuffer *evbuf;
while (1) {
char body[4096];
int body_len, clientId;
time_t start = time (NULL);
int i;
printf ("Please press enter: ");
fgets (body, sizeof (body), stdin);
for (i = 0; i < 1000; i++) {
sprintf (body, "Hello world #%d<br>", i + 1);
body_len = strlen (body);
printf ("Sending %d bytes to the clients: %s\n", body_len, body);
for (clientId = 0; clientId < MAXUSERS && clients[clientId] != NULL; clientId++) {
evbuf = evbuffer_new ();
evbuffer_add_printf (evbuf, "(%ld) %s<br>", time (NULL) - start, body);
printf ("Sending to client %d\n", clientId + 1);
evhttp_send_reply_chunk (clients[clientId], evbuf);
evbuffer_free (evbuf);
}
}
}
pthread_exit (0);
}
int
main (int argc, char **argv) {
pthread_t helper;
pthread_create (&helper, NULL, run, NULL);
int i;
for (i = 0; i < MAXUSERS; i++)
slots[i] = i;
// Launch libevent httpd:
struct evhttp *httpd;
event_init ();
httpd = evhttp_start ("0.0.0.0", 8000);
evhttp_set_gencb (httpd, request_handler, NULL);
event_dispatch ();
// Not reached, event_dispatch() shouldnât return
evhttp_free (httpd);
return 0;
}
_______________________________________________
Libevent-users mailing list
[email protected]
http://monkeymail.org/mailman/listinfo/libevent-users