mirror of
				https://gitlab.freedesktop.org/wayland/wayland.git
				synced 2025-11-03 09:01:42 -05:00 
			
		
		
		
	server: Add client destroy signal
This commit is contained in:
		
							parent
							
								
									18a770c80d
								
							
						
					
					
						commit
						fa5f7b1191
					
				
					 4 changed files with 121 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -63,6 +63,7 @@ struct wl_client {
 | 
			
		|||
	uint32_t mask;
 | 
			
		||||
	struct wl_list link;
 | 
			
		||||
	struct wl_map objects;
 | 
			
		||||
	struct wl_signal destroy_signal;
 | 
			
		||||
	struct ucred ucred;
 | 
			
		||||
	int error;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -336,6 +337,7 @@ wl_client_create(struct wl_display *display, int fd)
 | 
			
		|||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wl_signal_init(&client->destroy_signal);
 | 
			
		||||
	bind_display(client, display, 1, 1);
 | 
			
		||||
 | 
			
		||||
	wl_list_insert(display->client_list.prev, &client->link);
 | 
			
		||||
| 
						 | 
				
			
			@ -409,6 +411,20 @@ wl_resource_destroy(struct wl_resource *resource)
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WL_EXPORT void
 | 
			
		||||
wl_client_add_destroy_listener(struct wl_client *client,
 | 
			
		||||
			       struct wl_listener *listener)
 | 
			
		||||
{
 | 
			
		||||
	wl_signal_add(&client->destroy_signal, listener);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WL_EXPORT struct wl_listener *
 | 
			
		||||
wl_client_get_destroy_listener(struct wl_client *client,
 | 
			
		||||
			       wl_notify_func_t notify)
 | 
			
		||||
{
 | 
			
		||||
	return wl_signal_get(&client->destroy_signal, notify);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WL_EXPORT void
 | 
			
		||||
wl_client_destroy(struct wl_client *client)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -416,6 +432,8 @@ wl_client_destroy(struct wl_client *client)
 | 
			
		|||
	
 | 
			
		||||
	printf("disconnect from client %p\n", client);
 | 
			
		||||
 | 
			
		||||
	wl_signal_emit(&client->destroy_signal, client);
 | 
			
		||||
 | 
			
		||||
	wl_client_flush(client);
 | 
			
		||||
	wl_map_for_each(&client->objects, destroy_resource, &serial);
 | 
			
		||||
	wl_map_release(&client->objects);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,6 +75,8 @@ int wl_event_loop_get_fd(struct wl_event_loop *loop);
 | 
			
		|||
struct wl_client;
 | 
			
		||||
struct wl_display;
 | 
			
		||||
struct wl_input_device;
 | 
			
		||||
struct wl_listener;
 | 
			
		||||
typedef void (*wl_notify_func_t)(struct wl_listener *listener, void *data);
 | 
			
		||||
 | 
			
		||||
struct wl_display *wl_display_create(void);
 | 
			
		||||
void wl_display_destroy(struct wl_display *display);
 | 
			
		||||
| 
						 | 
				
			
			@ -106,6 +108,11 @@ void wl_client_flush(struct wl_client *client);
 | 
			
		|||
void wl_client_get_credentials(struct wl_client *client,
 | 
			
		||||
			       pid_t *pid, uid_t *uid, gid_t *gid);
 | 
			
		||||
 | 
			
		||||
void wl_client_add_destroy_listener(struct wl_client *client,
 | 
			
		||||
				    struct wl_listener *listener);
 | 
			
		||||
struct wl_listener *wl_client_get_destroy_listener(struct wl_client *client,
 | 
			
		||||
						   wl_notify_func_t notify);
 | 
			
		||||
 | 
			
		||||
struct wl_resource *
 | 
			
		||||
wl_client_add_object(struct wl_client *client,
 | 
			
		||||
		     const struct wl_interface *interface,
 | 
			
		||||
| 
						 | 
				
			
			@ -117,7 +124,7 @@ wl_client_new_object(struct wl_client *client,
 | 
			
		|||
 | 
			
		||||
struct wl_listener {
 | 
			
		||||
	struct wl_list link;
 | 
			
		||||
	void (*notify)(struct wl_listener *listener, void *data);
 | 
			
		||||
	wl_notify_func_t notify;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct wl_signal {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +1,20 @@
 | 
			
		|||
TESTS = $(check_PROGRAMS)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
check_PROGRAMS = array-test map-test list-test connection-test event-loop-test
 | 
			
		||||
check_PROGRAMS =				\
 | 
			
		||||
	array-test				\
 | 
			
		||||
	map-test				\
 | 
			
		||||
	list-test				\
 | 
			
		||||
	connection-test				\
 | 
			
		||||
	event-loop-test				\
 | 
			
		||||
	client-test
 | 
			
		||||
 | 
			
		||||
map_test_SOURCES = map-test.c test-runner.c test-runner.h
 | 
			
		||||
array_test_SOURCES = array-test.c test-runner.c
 | 
			
		||||
list_test_SOURCES = list-test.c test-runner.c
 | 
			
		||||
connection_test_SOURCES = connection-test.c test-runner.c
 | 
			
		||||
event_loop_test_SOURCES = event-loop-test.c test-runner.c
 | 
			
		||||
client_test_SOURCES = client-test.c test-runner.c
 | 
			
		||||
 | 
			
		||||
AM_CFLAGS = $(GCC_CFLAGS)
 | 
			
		||||
LDADD = $(top_builddir)/src/libwayland-util.la \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										87
									
								
								tests/client-test.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								tests/client-test.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,87 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright © 2012 Intel Corporation
 | 
			
		||||
 *
 | 
			
		||||
 * Permission to use, copy, modify, distribute, and sell this software and its
 | 
			
		||||
 * documentation for any purpose is hereby granted without fee, provided that
 | 
			
		||||
 * the above copyright notice appear in all copies and that both that copyright
 | 
			
		||||
 * notice and this permission notice appear in supporting documentation, and
 | 
			
		||||
 * that the name of the copyright holders not be used in advertising or
 | 
			
		||||
 * publicity pertaining to distribution of the software without specific,
 | 
			
		||||
 * written prior permission.  The copyright holders make no representations
 | 
			
		||||
 * about the suitability of this software for any purpose.  It is provided "as
 | 
			
		||||
 * is" without express or implied warranty.
 | 
			
		||||
 *
 | 
			
		||||
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
			
		||||
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
			
		||||
 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 | 
			
		||||
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 | 
			
		||||
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 | 
			
		||||
 * OF THIS SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
#include "../src/wayland-server.h"
 | 
			
		||||
#include "test-runner.h"
 | 
			
		||||
 | 
			
		||||
struct client_destroy_listener {
 | 
			
		||||
	struct wl_listener listener;
 | 
			
		||||
	int done;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
client_destroy_notify(struct wl_listener *l, void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct client_destroy_listener *listener =
 | 
			
		||||
		container_of(l, struct client_destroy_listener, listener);
 | 
			
		||||
 | 
			
		||||
	listener->done = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(client_destroy_listener)
 | 
			
		||||
{
 | 
			
		||||
	struct wl_display *display;
 | 
			
		||||
	struct wl_client *client;
 | 
			
		||||
	struct client_destroy_listener a, b;
 | 
			
		||||
	int s[2];
 | 
			
		||||
 | 
			
		||||
	assert(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, s) == 0);
 | 
			
		||||
	display = wl_display_create();
 | 
			
		||||
	assert(display);
 | 
			
		||||
	client = wl_client_create(display, s[0]);
 | 
			
		||||
	assert(client);
 | 
			
		||||
 | 
			
		||||
	a.listener.notify = client_destroy_notify;
 | 
			
		||||
	a.done = 0;
 | 
			
		||||
	wl_client_add_destroy_listener(client, &a.listener);
 | 
			
		||||
 | 
			
		||||
	assert(wl_client_get_destroy_listener(client, client_destroy_notify) ==
 | 
			
		||||
	       &a.listener);
 | 
			
		||||
 | 
			
		||||
	b.listener.notify = client_destroy_notify;
 | 
			
		||||
	b.done = 0;
 | 
			
		||||
	wl_client_add_destroy_listener(client, &b.listener);
 | 
			
		||||
 | 
			
		||||
	wl_list_remove(&a.listener.link);
 | 
			
		||||
 | 
			
		||||
	wl_client_destroy(client);
 | 
			
		||||
 | 
			
		||||
	assert(!a.done);
 | 
			
		||||
	assert(b.done);
 | 
			
		||||
 | 
			
		||||
	close(s[0]);
 | 
			
		||||
	close(s[1]);
 | 
			
		||||
 | 
			
		||||
	wl_display_destroy(display);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue