On 04/17/2015 11:47 AM, Denis Shilkin wrote:
> Hi guys! I found strange behaviour in libuv. Help me to understand is it
> a bug, or something wrong with me:-)
> 
> Info:
> libuv from github (master, 1.4.2, 1.x) tested with optimization and
> without, in debug and in release mode
> gcc version 4.9.1 (Ubuntu 4.9.1-16ubuntu6)
> Ubuntu 14.10
> 
> My use case:
> I want to send lots of unique uv_async_t, and all callbacks should be
> invoked. So I need to have different uv_async_t for each sending.
> In each callback that would be invoked I need to close a handle because
> it's not need anymore.
> To keep event loop running I send "blocking" uv_async_t and don't close
> it to keep a handle in active state.
> 

What do you mean by "blocking" here? You just keep an async handle around?

> Strange:
> I found that !sometimes! uv_run() stops.
> 

Do you unref the handle? Do you call uv_stop?

> Trying to figure out:
> I started to debug my code and found that uv_run sometimes quits because
> uv__loop_alive(loop) return 0.
> It happens because uv__has_active_handles(loop) becomes false, due to
> ((loop)->active_handles > 0) condition is false.
> Why the condition is false when there should be at least one active
> handle in the loop, which was sent and was not closed?
> It sounds like a joke, but in case uv_run don't quit the value of
> loop->active_handles is about UINT_MAX!
> Look the code of libuv: "unsigned int active_handles". If we have value
> about UINT_MAX than we decrement this variable more than needed!

How may async handles are you creating? Maybe you created an overflow.

> 
> I found that there is 1 place where loop->active_handles decrements:
> uv__active_handle_rm(h).
> And there is 2 sequences of function invocation which lead to this call,
> they are:
>     1. uv_run -> uv_async_close -> uv_handles_stop -> uv_active_handle_rm
>     2. uv_close -> uv_async_close -> uv_handles_stop -> uv_active_handle_rm
> 
> I supose that there is 2 ways why it can be:
>     1. libuv don't increment loop->active_handles sometimes but decrement it
>     2. libuv decrement loop->active_handles more than needed
> 
> Test example:
> #include <uv.h>
> 
> int main()
> {
>     uv_loop_t *loop = uv_default_loop();
>    
>     // Blocking async, need to loop don't quit from run
>     uv_async_t async;
>     uv_async_init(loop, &async, [](uv_async_t* a){
>         std::cout << "blocking active handle\n";
>         // no close! it's an active handle
>     });
>     uv_async_send(&async);
>    
>     // Create thread for event loop
>     uv_thread_t th;
>     uv_thread_create(&th,
>                     [](void *arg)
>                     {
>                         uv_run((uv_loop_t*)arg, UV_RUN_DEFAULT);
>                         std::cout << "Quit from event loop\n";
>                     },
>                     loop
>     ); // uv_thread_create
>                    
>     // Send lots of async events
>     uv_async_t asyncs[1000];
>     for (int i=0; i<1000; i++)
>     {
>         asyncs[i] = uv_async_t();
>         uv_async_init(loop, &asyncs[i], [](uv_async_t* a)
>         {
>             std::cout << "async\n";
>             // async not need anymore - close it
>             // after that handle becomes inactive
>             uv_close((uv_handle_t*)a, [](uv_handle_t*)
>             {
>                 // may free uv_handle_t->data here
>                 std::cout << "close\n";
>             });
>         });
>         uv_async_send(&asyncs[i]);
>     }               
>    
>     uv_thread_join(&th);
>    
>     return 0;
> }
> 

Ah, I see now. You are calling uv_async_init in another thread. THat's
not safe. *Only* uv_async_send is.


Regards,

-- 
Saúl Ibarra Corretgé
bettercallsaghul.com


-- 
You received this message because you are subscribed to the Google Groups 
"libuv" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/libuv.
For more options, visit https://groups.google.com/d/optout.

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to