How to create client in child thread

Pekka Paalanen ppaalanen at gmail.com
Thu Jun 23 13:13:28 UTC 2016


On Thu, 23 Jun 2016 14:52:23 +0800 (CST)
袁嘉伟 <yuanjw1025 at 163.com> wrote:

> Hi Pekka:
> 
> Sorry to take you some time. It's still this issue.
> I made a test that using 'pthread' to created another thread, and then created the display in the child thread.
> But program was blocked when connecting to a server(wl_display_connect). It should be pending according to log.
> However, I called the renderFrames() in main thread, it ran correctly and displayed the triangle.
> Could you tell me what causes the issue happend. 
> 
> 
> 
> 
> voidSurfaceManagerClient::initializeThread()
> {
>     pthread_t lifeThread;
> pthread_create(&lifeThread, NULL, &SurfaceManagerClient::renderFrames, NULL);    
> }
> 
> 
> void SurfaceManagerClient::renderFrames()
> {
> struct sigaction sigint;
> struct display display = { 0 };
> struct window  window  = { 0 };
> int i, ret = 0;
> window.display = &display;
> display.window = &window;
> window.window_size.width  = 250;
> window.window_size.height = 250;
> window.buffer_size = 32;
> window.frame_sync = 1;
> for (i = 1; i < m_argc; i++) {
> if (strcmp("-f", m_argv[i]) == 0)
> window.fullscreen = 1;
> else if (strcmp("-o", m_argv[i]) == 0)
> window.opaque = 1;
> else if (strcmp("-s", m_argv[i]) == 0)
> window.buffer_size = 16;
> else if (strcmp("-b", m_argv[i]) == 0)
> window.frame_sync = 0;
> else if (strcmp("-h", m_argv[i]) == 0)
> usage(EXIT_SUCCESS);
> else
> usage(EXIT_FAILURE);
> }
> display.display = wl_display_connect(NULL);
> assert(display.display);
> display.registry = wl_display_get_registry(display.display);
> wl_registry_add_listener(display.registry, &registry_listener, &display);
> 
> 
> int a = wl_display_dispatch(display.display);
> init_egl(&display, &window);
> create_surface(&window);
> init_gl(&window);
> display.cursor_surface = wl_compositor_create_surface(display.compositor);
> 
> 
> sigint.sa_handler = signal_int;
> sigemptyset(&sigint.sa_mask);
> sigint.sa_flags = SA_RESETHAND;
> sigaction(SIGINT, &sigint, NULL);
> 
> 
> while (running && ret != -1) {
> wl_display_dispatch_pending(display.display);
> redraw(&window, NULL, 0);
> }
>     fprintf(stderr, "simple-egl exiting\n");
>     destroy_surface(&window);
> 
>     fini_egl(&display);
> 	wl_surface_destroy(display.cursor_surface);
> 	if (display.cursor_theme)
> 		wl_cursor_theme_destroy(display.cursor_theme);
> 
> 	if (display.shell)
> 		xdg_shell_destroy(display.shell);
> 
> 	if (display.ivi_application)
> 		ivi_application_destroy(display.ivi_application);
> 
> 	if (display.compositor)
> 		wl_compositor_destroy(display.compositor);
> 
> 	wl_registry_destroy(display.registry);
> 	wl_display_flush(display.display);
> 	wl_display_disconnect(display.display);
> 
> 	return 0;
> }
> Best regards,
> Anthenony
> 
> 
> >Oh indeed, sorry for my confusion. First, some general background >information: > >eglSwapBuffers() counts as a Wayland protocol call, because it is >guaranteed to call wl_surface.commit before it returns and with the >newly rendered buffer attached, and it will also wait for >wl_buffer.release events if necessary, and by default it also waits for >wl_surface.frame callbacks to return. > >Here is what I wrote about EGL elsewhere: > > eglSwapBuffers will be waiting for the previous eglSwapBuffers' > frame callback and only if it has not arrived already for the > particular surface. If you call eglSwapBuffers as a response to > receiving your own copy of the frame callback or later, > eglSwapBuffers will never block. > > To be more precise, wait for the frame callback happens on the > eglSwapBuffers *after* the current one as I explained above, > and waits for wl_buffer.releases happen at the first draw call > that would need a buffer to draw into if necessary. > > Those are the two orthogonal throttling mechanisms in Mesa. > Setting swap interval to 0 will prevent waits for the frame > callbacks, but not for buffer releases, because Mesa does not > want to potentially allocate an unlimited number of buffers in > case the server is slow to send out releases (which would imply > your whole system is already hosed anyway, so putting even more > pressure to it would only make things worse). > >The above describes the expected behaviour of EGL. Bugs, which we know >to be around, are another matter. > >Do note, that I am only talking about Mesa and what a proper EGL >implementation would do. If you are using any properietary EGL >implementation, especially Vivante, you might be in trouble. > >Other things you must take care of are: > >- every thread where you want Wayland events dispatched must have its > own wl_event_queue (Mesa EGL creates one for itself) > >- you must use the wl_display_prepare_read() API of libwayland-client > in all callers of libwayland-client properly > >- Pay attention to all bugs linked from > https://bugs.freedesktop.org/show_bug.cgi?id=91769 , > particularly https://bugs.freedesktop.org/show_bug.cgi?id=91273 which > also requires a fix in the EGL implementation (for Mesa, see > https://lists.freedesktop.org/archives/mesa-dev/2016-May/115617.html > for a patch that does not seem to have been even merged yet). > >In general, Wayland functions are *not* meant for controlling things >across thread boundaries. It is safe to send requests from multiple >threads, but you are still responsible for ordering them correctly >yourself in cases where the order matters. > >If this gives you the impression that using threads with EGL/Wayland in >particular is rare and not really tested, you are right. I do not know >of any good code examples, maybe others have some? > >You say you are blocked in eglGetDisplay(). I have not heard of that >before. Which EGL implementation is that? If it is not Mesa, and you >cannot reproduce the problem with Mesa, then I suspect you have to >contact your EGL vendor about it. > > >Thanks, >p  


Hi,

sorry, but I can't make sense from the spaghetti above, nor do I have
time to debug your application for you, especially when it has huge
parts outside of my expertise (everything about SurfaceManager). If you
can create a stand-alone C program that shows the problem, then it
might be possible to take a look, but no promises.

Also signals will be delivered to random threads unless you
specifically block them.

I have no idea why wl_display_connect() from a secondary thread would
block.


Thanks,
pq
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 811 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20160623/24139b9a/attachment.sig>


More information about the wayland-devel mailing list