<div dir="ltr">On Tue, Jul 14, 2015 at 6:26 AM, Pekka Paalanen <span dir="ltr"><<a href="mailto:ppaalanen@gmail.com" target="_blank">ppaalanen@gmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class=""><br>
>     bar = wl_new_bar();<br>
>     wl_proxy_set_queue((struct wl_proxy*)bar, queue); // default queue if<br>
> this not done<br>
>     wl_bar_add_listener(bar, ...);<br>
>     wl_foo_get_bar(foo, bar);<br>
><br>
> Note the last function will have to be renamed to avoid a collision in C<br>
> but I don't have any good ideas what to name it.<br>
<br>
</span>FWIW, this is roughly how Wayland API originally worked. It had to be<br>
changed, because it had a race in object id allocation and request<br>
sending, and both sides of the IPC expect object ids to be allocated in<br>
order.<br>
<br>
As id allocation must happen in the same order as sending the requests,<br>
you cannot split them, because another thread might run in between and<br>
send another request creating another new object, which screws up the<br>
id allocation ordering.<br>
<br>
Why they have to be allocated in order I no longer remember, if I ever<br>
knew.<br></blockquote><div><br></div><div>My guess is they don't really have to be in order, but that it was desirable to avoid the overhead of two locks (one for allocating an objectId and a second for the wl_connection_write), by using one lock around them all.<br></div><div><br></div><div>In fact you are grabbing a lock in wl_proxy_marshal_array_constructor surrounding the creation of the wl_proxy object and the queuing of the message (the closure_send). But this means quite a lot of code is surrounded by this lock and thus is single threaded. This includes the malloc of the wl_proxy, the wl_closure, and a buffer inside wl_closure_send, and the initializing of all this data. The lock also surrounds the free of the wl_closure and the buffer. This seems like a mistake.<br><br></div><div>I would think a wl_proxy could exist without an objectId allocated. Then you could allocate the id right next to the wl_connection_write in wl_closure_send, and the lock is only around these two statements. This would make a much smaller piece of code single-threaded, it would also preserve the objectid allocation and message order if that really is necessary, and still only use one lock. And it would allow the wl_proxy to be created and modified before it is assigned to an actual object.<br><br></div><div>This would require wl_closure_send to understand newid arguments, just like it is special-casing fd arguments.<br><br></div><div><br></div></div></div></div>