[Libevent-users] thread-safety (and performance)

2008-01-21 Thread Tani Hosokawa
When initiating HTTP requests in a multi-threaded process, under any 
significant load you will start finding horrible memory corruption 
problems, sometimes resulting in bad requests and sometimes resulting in 
core dumps.  Also, under any significant load, you'll probably find that 
you are dropping a large number of connections due to the listen queue 
overflowing while your code is performing some other task.  This is a 
patch that I think largely deals with these.  Also, http_hostportfile() 
is not thread-safe, so I've attached a thread-safe version that can be 
used in its place (unfortunately I can't think of any clean way to make 
the current interface thread-safe without introducing a memory leak).


/* TH: remember to free() opaque after you're done with this */
int
http_hostportfile_r(const char *url, char **phost, u_short *pport, char 
**pfile,void **opaque)

{
   struct http_hostportfile_threadsafe_opaque {
  char shost[1024];
  char sfile[1024];
   } *opaquedata;
   opaquedata = malloc(sizeof(*opaquedata));
   *opaque = opaquedata;
   char *p, *p2;
   int len;
   u_short port;

   len = strlen(HTTP_PREFIX);
   if (strncasecmp(url, HTTP_PREFIX, len))
   return (-1);

   url += len;

   /* We might overrun */
   if (strlcpy(opaquedata-shost, url, sizeof(opaquedata-shost)) 
= sizeof(opaquedata-shost))

   return (-1);

   p = strchr(opaquedata-shost, '/');
   if (p != NULL) {
   *p = '\0';
   p2 = p + 1;
   } else
   p2 = NULL;

   if (pfile != NULL) {
   /* Generate request file */
   if (p2 == NULL)
   p2 = ;
   snprintf(opaquedata-sfile, sizeof(opaquedata-sfile), 
/%s, p2);

   }

   p = strchr(opaquedata-shost, ':');
   if (p != NULL) {
   *p = '\0';
   port = atoi(p + 1);

   if (port == 0)
   return (-1);
   } else
   port = HTTP_DEFAULTPORT;

   if (phost != NULL)
   *phost = opaquedata-shost;
   if (pport != NULL)
   *pport = port;
   if (pfile != NULL)
   *pfile = opaquedata-sfile;

   return (0);
}


Index: http.c
===
--- http.c  (revision 1)
+++ http.c  (working copy)
@@ -308,7 +308,7 @@
evhttp_make_header_request(struct evhttp_connection *evcon,
struct evhttp_request *req)
{
-   static char line[1024];
+   char line[1024];
   const char *method;

   evhttp_remove_header(req-output_headers, Accept-Encoding);
@@ -378,9 +378,9 @@
evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
long content_length)
{
+   char len[12]; /* XXX: not thread-safe */
   if (evhttp_find_header(headers, Transfer-Encoding) == NULL 
   evhttp_find_header(headers, Content-Length) == NULL) {
-   static char len[12]; /* XXX: not thread-safe */
   snprintf(len, sizeof(len), %ld, content_length);
   evhttp_add_header(headers, Content-Length, len);
   }
@@ -394,7 +394,7 @@
evhttp_make_header_response(struct evhttp_connection *evcon,
struct evhttp_request *req)
{
-   static char line[1024];
+   char line[1024];
   snprintf(line, sizeof(line), HTTP/%d.%d %d %s\r\n,
   req-major, req-minor, req-response_code,
   req-response_code_line);
@@ -433,7 +433,7 @@
void
evhttp_make_header(struct evhttp_connection *evcon, struct 
evhttp_request *req)

{
-   static char line[1024];
+   char line[1024];
   struct evkeyval *header;

   /*
@@ -1999,7 +1999,7 @@
   if ((fd = bind_socket(address, port)) == -1)
   return (-1);

-   if (listen(fd, 10) == -1) {
+   if (listen(fd, 8192) == -1) {
   event_warn(%s: listen, __func__);
   EVUTIL_CLOSESOCKET(fd);
   return (-1);

___
Libevent-users mailing list
Libevent-users@monkey.org
http://monkeymail.org/mailman/listinfo/libevent-users


Re: [Libevent-users] thread-safety (and performance)

2008-01-21 Thread William Ahern
On Mon, Jan 21, 2008 at 04:14:08PM -0800, Tani Hosokawa wrote:
snip
 @@ -1999,7 +1999,7 @@
if ((fd = bind_socket(address, port)) == -1)
return (-1);
 
 -   if (listen(fd, 10) == -1) {
 +   if (listen(fd, 8192) == -1) {
event_warn(%s: listen, __func__);
EVUTIL_CLOSESOCKET(fd);
return (-1);

Probably better to use SOMAXCONN instead of an arbitrary number.

___
Libevent-users mailing list
Libevent-users@monkey.org
http://monkeymail.org/mailman/listinfo/libevent-users