]> err.no Git - varnish/commitdiff
I have grumbled about the evilness of "current_base" before, and this just
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 3 Jul 2006 19:35:05 +0000 (19:35 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 3 Jul 2006 19:35:05 +0000 (19:35 +0000)
proves the point:  If two threads call event_init() at the same time,
they will both stomp on the same memory via current_base, and in all
likelyhood, neither of them will manage to get the job done properly.

Instead work on a local variable and don't assign to current_base
until the setup is complete.

This should be submitted to Niels Provos

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@288 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/contrib/libevent/event.c

index 8621f6c27d29684aaa98601bb426681dd5278467..9496edcc8969df63290e2dc99393ad8b189eb934 100644 (file)
@@ -164,36 +164,38 @@ void *
 event_init(void)
 {
        int i;
+       struct event_base *mybase;
 
-       if ((current_base = calloc(1, sizeof(struct event_base))) == NULL)
+       if ((mybase = calloc(1, sizeof(struct event_base))) == NULL)
                event_err(1, "%s: calloc");
 
        event_sigcb = NULL;
        event_gotsig = 0;
-       gettime(&current_base->event_tv);
+       gettime(&mybase->event_tv);
        
-       RB_INIT(&current_base->timetree);
-       TAILQ_INIT(&current_base->eventqueue);
+       RB_INIT(&mybase->timetree);
+       TAILQ_INIT(&mybase->eventqueue);
        TAILQ_INIT(&signalqueue);
        
-       current_base->evbase = NULL;
-       for (i = 0; eventops[i] && !current_base->evbase; i++) {
-               current_base->evsel = eventops[i];
+       mybase->evbase = NULL;
+       for (i = 0; eventops[i] && NULL == mybase->evbase; i++) {
+               mybase->evsel = eventops[i];
 
-               current_base->evbase = current_base->evsel->init();
+               mybase->evbase = mybase->evsel->init();
        }
 
-       if (current_base->evbase == NULL)
+       if (mybase->evbase == NULL)
                event_errx(1, "%s: no event mechanism available", __func__);
 
        if (getenv("EVENT_SHOW_METHOD")) 
                event_msgx("libevent using: %s\n",
-                          current_base->evsel->name);
+                          mybase->evsel->name);
 
        /* allocate a single active event queue */
-       event_base_priority_init(current_base, 1);
+       event_base_priority_init(mybase, 1);
 
-       return (current_base);
+       current_base = mybase;
+       return (mybase);
 }
 
 void