[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [Libevent-users] Help with progress thread



Afraid I am hitting a brick wall, Nick. I can't make the threaded code work. Perhaps you have some further advice?

I have attached my test code. Basically, it initializes the event lib, calls use_threads, creates a new base, and then spawns a progress thread that calls event_loop (you'll see that we prepended "opal" to your calls as part of an abstraction requirement - but I believe the calls are still understandable). The call to event_init is embedded in opal_init.

What I find is the following:

1. if I immediately setup the write event, then the thread somehow sees it and acts correctly.

2. if I add any delay between starting the thread and creating the write event, then the thread never sees it - it just sits there

3. if I trigger an event after creating the write event and force the thread out of the event loop, it still doesn't see the new write event when it re-enters the loop.

Here is the debug output (some of it ours) from option #3 - this is running on Mac OSX:

Ralph:system rhc$ ./event-threads
[Ralph:32322] event: available subsystems: poll, select
SETTING UP TO USE THREADS
[debug] event_add: event: 0x10060a7e8, EV_READ   call 0x1000b3021
[debug] event_add: event: 0x100002380, EV_READ   call 0x1000017bf
Looping...
[debug] event_add: event: 0x1000022e0,  EV_WRITE  call 0x100001a21
Waiting...
[debug] select_dispatch: select reports 1
[debug] event_del: 0x100002380, callback 0x1000017bf
[debug] event_process_active: event: 0x100002380, EV_READ  call 0x1000017bf
[debug] event_add: event: 0x100002380, EV_READ   call 0x1000017bf
[debug] event_base_loop: asked to terminate loop.
Looping...
Waiting...
Waiting...
Waiting...
Waiting...
Waiting...
Waiting...
Waiting...
Waiting...
Waiting...
[debug] select_dispatch: select reports 1
[debug] event_del: 0x100002380, callback 0x1000017bf
[debug] event_process_active: event: 0x100002380, EV_READ  call 0x1000017bf
[debug] event_add: event: 0x100002380, EV_READ   call 0x1000017bf
[debug] event_base_loop: asked to terminate loop.
Thread stopping
[debug] event_del: 0x100002380, callback 0x1000017bf
[debug] event_del: 0x100609ab8, callback 0x1000b3021


One thing we noted: while there are thread locks, there are no volatile declarations inside the libevent code. This strikes some of us as looking eerily similar to problems normally seen when threads modify common non-volatile data.

Any suggestions would be greatly appreciated!
Ralph

Attachment: event-threads.c
Description: Binary data


On Nov 10, 2010, at 10:20 AM, Nick Mathewson wrote:

> On Wed, Nov 10, 2010 at 9:58 AM, Ralph Castain <rhc@xxxxxxxxxxxx> wrote:
>> 
>> On Nov 9, 2010, at 9:57 PM, Nick Mathewson wrote:
>> 
>>> On Tue, Nov 9, 2010 at 11:47 PM, Ralph Castain <rhc@xxxxxxxxxxxx> wrote:
>>>> 
>>>> On Nov 9, 2010, at 9:03 PM, Nick Mathewson wrote:
>>> [...]
>>>>> So I'm assuming that you've got all the threading callbacks set up
>>>>> (probably via evthread_use_pthreads()) before you created the event
>>>>> base, so that evthread_make_base_notifiable() was called on the
>>>>> event_base when you created it.  If that's not the case, that's
>>>>> probably the problem there.
>>>> 
>>>> I missed that - this may well be my problem. Let me dig into this a little and get back to you.
>>>> 
>>>> FWIW: I don't see myself drop out of the event loop when I add the event. In fact, just the opposite - I'm stuck in the loop and can't get out. So I'm not sure the bug mentioned below is accurate.
>>>> 
>>>> Let me see what happens when I setup the event base for notification.
>>> 
>>> To clarify, it should set itself up to be notifiable if you have
>>> threading initialized before you create it.  (If you're going to
>>> access an event_base from multiple threads, you MUST initialize
>>> threading, or else there won't be any locks, and you'll be in a world
>>> of race conditions.)
>>> 
>>> Then again, calling evthread_make_base_notifiable() on an existing
>>> event_base shouldn't hurt, since it's (supposed to be) idempotent.
>> 
>> I'm confused - the function you cite requires an event base be passed to it:
>> 
>> int evthread_make_base_notifiable(struct event_base *base);
>> 
>> So how can I call it -before- I create the event base?
> 
> Initializing threading is not the same as making a base notifiable.
> These are different things.
> 
> You need to initialize threading before you create the base.  That's
> why you call evthread_use_pthreads().
> 
> Doing so should make the base get set up as notifiable.
> 
> If that doesn't work for some reason, you could try calling the
> function to make the base notifiable.
> 
> HTH,
> -- 
> Nick
> ***********************************************************************
> To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
> unsubscribe libevent-users    in the body.