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 Libevent-users@monkey.org http://monkeymail.org/mailman/listinfo/libevent-users