How to create client in child thread

袁嘉伟 yuanjw1025 at 163.com
Thu Jun 23 06:52:23 UTC 2016


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, >pq
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20160623/032d5620/attachment-0001.html>


More information about the wayland-devel mailing list