On Tue, Nov 6, 2012 at 7:37 AM, Nick Mathewson <ni...@freehaven.net> wrote:

>
> On Tue, Nov 6, 2012 at 12:29 AM, Himanshu S <mail2himan...@gmail.com>wrote:
>
>> Hi,
>>    I am using bufferevent_* APIs for my application to read/write data to
>> TCP stream. When the data arrives, the read callback happens, I want to
>> read partial data (at times), and then be able to post an event back so
>> that the event is queued up and read callback is called again. I thought
>> event_active() gives this functionality but apparently its not. I am using
>> event_active with following parameters,
>>
>> event_active(&bev->ev_read, EV_READ, 1);
>>
>
> That is _really_ not supported. Anything that touches bufferevent
> internals is going to get you potentially unpredicted results.
>
> Nick, Thanks for the quick response & help. Yes, I understand that correct
way of doing this would be to have an API in bufferevent & taking
BEV_LOCK().

Right now the best way to do what you have in mind is to consider *why* you
> only want to read partial data and then read again after the next event
> loop -- there's usually a better way to do whatever you're trying to
> achieve.
>

The main reason for doing this is to avoid spending unfair amount of time
on a single stream.


>  But if there isn't, and you want to make sure your code works with future
> versions of Libevent, your best bet is either to add a feature like this in
> Libevent 2.1, or to create a separate event whose callback will also run
> the bufferevent's callback, and activate that one.
>
> Is it true that the event_active() works only from a different thread? I
see event_active() eventually calls event_callback_activate_nolock_() & it
checks if the thread_id is different. So event if I create a separate event
& call event_active() on that event, from the same thread, would it still
work?

int
event_callback_activate_nolock_(struct event_base *base,
    struct event_callback *evcb)
{

...

    event_queue_insert_active(base, evcb);

    if (EVBASE_NEED_NOTIFY(base)) <-----
        evthread_notify_base(base);

    return r;
}

#define EVBASE_NEED_NOTIFY(base)             \
    (evthread_id_fn_ != NULL &&             \
        (base)->running_loop &&             \
        (base)->th_owner_id != evthread_id_fn_()) <----


Again, Thanks for your help.



hth,
> --
> Nick
>

Reply via email to