aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/wth-receiver-comm.h4
-rw-r--r--src/wth-receiver-comm.c60
-rw-r--r--src/wth-receiver-gst-shm.c10
-rw-r--r--src/wth-receiver-main.c69
-rw-r--r--src/wth-receiver-seat.c9
5 files changed, 121 insertions, 31 deletions
diff --git a/include/wth-receiver-comm.h b/include/wth-receiver-comm.h
index 4499053..fc6e6ae 100644
--- a/include/wth-receiver-comm.h
+++ b/include/wth-receiver-comm.h
@@ -131,6 +131,7 @@ struct ivisurface {
struct wthp_callback *cb;
struct wl_list link; /* struct client::surface_list */
struct surface *surf;
+ struct application_id *appid;
};
/* wthp_ivi_application protocol object */
@@ -164,6 +165,9 @@ struct client {
struct wl_list link; /* struct receiver::client_list */
struct receiver *receiver;
+ pid_t pid;
+ bool pid_destroying;
+
struct wth_connection *connection;
struct watch conn_watch;
diff --git a/src/wth-receiver-comm.c b/src/wth-receiver-comm.c
index e6c0266..0527ecd 100644
--- a/src/wth-receiver-comm.c
+++ b/src/wth-receiver-comm.c
@@ -34,12 +34,16 @@
** **
** **
*******************************************************************************/
+#include <sys/types.h>
+#include <signal.h>
#include "wth-receiver-comm.h"
#include "wth-receiver-surface.h"
#include "wth-receiver-seat.h"
#include "wth-receiver-buffer.h"
+#include <waltham-util.h>
+
extern uint16_t tcp_port;
extern const char *my_app_id;
@@ -59,9 +63,17 @@ static void
wthp_ivi_surface_destroy(struct wthp_ivi_surface * ivi_surface)
{
struct ivisurface *ivisurf = wth_object_get_user_data((struct wth_object *)ivi_surface);
-
- if (ivisurf->surf->ivi_app_id)
- free(ivisurf->surf->ivi_app_id);
+ struct client *client = ivisurf->appid->client;
+
+ if (client) {
+ client->pid_destroying = true;
+ fprintf(stdout, "client pid_destroying to true for client %p pid %d\n",
+ client, client->pid);
+ if (kill(client->pid, SIGINT) < 0) {
+ fprintf(stderr, "Failed to send SIGINT to child %d\n",
+ client->pid);
+ }
+ }
free(ivisurf);
}
@@ -80,34 +92,42 @@ wthp_ivi_app_id_surface_create(struct wthp_ivi_app_id *ivi_application,
struct wthp_surface * wthp_surface,
struct wthp_ivi_surface *obj)
{
- struct surface *surface = wth_object_get_user_data((struct wth_object *)wthp_surface);
-
- /* we destroy it wthp_ivi_surface_implementation:: */
- if (my_app_id) {
- surface->ivi_app_id = strdup(my_app_id);
- surface->shm_window->app_id = surface->ivi_app_id;
- }
-
- struct ivisurface *ivisurf;
+ struct surface *surface =
+ wth_object_get_user_data((struct wth_object *)wthp_surface);
+ struct application_id *appid =
+ wth_object_get_user_data((struct wth_object *) ivi_application);
+ pid_t cpid;
- ivisurf = zalloc(sizeof *ivisurf);
+ struct ivisurface *ivisurf = zalloc(sizeof *ivisurf);
if (!ivisurf) {
return;
}
ivisurf->obj = obj;
ivisurf->surf = surface;
+ ivisurf->appid = appid;
wthp_ivi_surface_set_interface(obj,
&wthp_ivi_surface_implementation, ivisurf);
- if (my_app_id)
- wth_receiver_weston_main(surface->shm_window, my_app_id, tcp_port);
- else
- wth_receiver_weston_main(surface->shm_window, app_id, tcp_port);
+ cpid = fork();
+ if (cpid == -1) {
+ fprintf(stderr, "Failed to fork()\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (cpid == 0) {
+ if (my_app_id)
+ wth_receiver_weston_main(surface->shm_window, my_app_id, tcp_port);
+ else
+ wth_receiver_weston_main(surface->shm_window, app_id, tcp_port);
+ } else {
+ /* this is parent, in wthp_ivi_surface_destroy() we mark that the
+ * client should be waited for so wait4() will be blocked.
+ */
+ appid->client->pid = cpid;
+ }
- while (!surface->shm_window->ready)
- usleep(1);
}
static const struct wthp_ivi_app_id_interface wthp_ivi_app_id_implementation = {
@@ -387,6 +407,7 @@ client_create(struct receiver *srv, struct wth_connection *conn)
disp = wth_connection_get_display(c->connection);
wth_display_set_interface(disp, &display_implementation, c);
+ fprintf(stdout, "Client %p created\n", c);
return c;
}
@@ -444,7 +465,6 @@ receiver_accept_client(struct receiver *srv)
wth_error("Failed to accept a connection.\n");
return;
}
-
client = client_create(srv, conn);
if (!client) {
wth_error("Failed client_create().\n");
diff --git a/src/wth-receiver-gst-shm.c b/src/wth-receiver-gst-shm.c
index 2228d4f..50efe0b 100644
--- a/src/wth-receiver-gst-shm.c
+++ b/src/wth-receiver-gst-shm.c
@@ -815,7 +815,7 @@ wth_receiver_weston_main(struct window *window, const char *app_id, int port)
memset(pipeline, 0x00, sizeof(pipeline));
snprintf(pipeline, sizeof(pipeline), pipe, port);
- fprintf(stdout, "pipeline %s\n", pipeline);
+ fprintf(stdout, "Using pipeline %s\n", pipeline);
/* parse the pipeline */
gstctx.pipeline = gst_parse_launch(pipeline, &gerror);
@@ -836,7 +836,6 @@ wth_receiver_weston_main(struct window *window, const char *app_id, int port)
while (running && ret != -1)
ret = wl_display_dispatch(gstctx.display->display);
-
gst_element_set_state(gstctx.pipeline, GST_STATE_NULL);
gst_object_unref(gstctx.pipeline);
@@ -844,5 +843,10 @@ wth_receiver_weston_main(struct window *window, const char *app_id, int port)
destroy_display(gstctx.display);
free(gargv);
- return 0;
+ fprintf(stdout, "Exiting, closed down gstreamer pipeline\n");
+ /* note, we do a exit here because wth_receiver_weston_main() isn't
+ * really C's main() and we fork() before calling this. Doing a return
+ * will not correctly signal the parent that the child process exited
+ */
+ exit(EXIT_SUCCESS);
}
diff --git a/src/wth-receiver-main.c b/src/wth-receiver-main.c
index 8af8eda..54f73eb 100644
--- a/src/wth-receiver-main.c
+++ b/src/wth-receiver-main.c
@@ -34,6 +34,11 @@
*******************************************************************************/
#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+#include <unistd.h>
+
#include "wth-receiver-comm.h"
#define MAX_EPOLL_WATCHES 2
@@ -150,6 +155,46 @@ listen_socket_handle_data(struct watch *w, uint32_t events)
}
}
+static void
+receiver_clean_up_child(pid_t pid, struct receiver *srv)
+{
+ struct client *client;
+
+ /* client represents connection with the transmitter, so removing it
+ * from the client list isn't what need to happen. Mark the
+ * pid_destroying as to give it a chance for next time */
+ wl_list_for_each(client, &srv->client_list, link) {
+ if (client->pid == pid) {
+ client->pid_destroying = false;
+ }
+ }
+}
+
+static void
+wait_for_children(struct receiver *srv, pid_t pid)
+{
+ pid_t w;
+ int status;
+ int options = WUNTRACED | WCONTINUED;
+
+ do {
+ w = waitpid(pid, &status, options);
+ if (w == -1) {
+ fprintf(stderr, "err no children to wait for!\n");
+ }
+
+ if (WIFEXITED(status)) {
+ if (w > 0) {
+ receiver_clean_up_child(w, srv);
+ }
+ } else if (WIFSIGNALED(status)) {
+ // FIXME should remove the client here, and identify with the pid
+ } else if (WIFSTOPPED(status)) {
+ } else if (WIFCONTINUED(status)) {
+ }
+
+ } while (!WIFEXITED(status) && !WIFSIGNALED(status));
+}
/**
* receiver_mainloop
*
@@ -173,9 +218,33 @@ receiver_mainloop(struct receiver *srv)
while (srv->running) {
/* Run any idle tasks at this point. */
+ bool should_wait_for_children = false;
+ struct client *client;
receiver_flush_clients(srv);
+ wl_list_for_each(client, &srv->client_list, link) {
+ if (client->pid > 0 && client->pid_destroying) {
+ should_wait_for_children = true;
+ break;
+ }
+ }
+
+ /*
+ * wait_for_children() will block and wait for children that
+ * died out/terminated correctly as the remote that end sent
+ * the destroy surface request. pid_destroying is the one that
+ * allows to make that distinction and will be set by the
+ * destroy surface handler.
+ *
+ * 'children' is just one. A new child will be started when the
+ * remote side sents a request to create a surface and will be
+ * killed in the handler that destroys the surface.
+ */
+ if (should_wait_for_children)
+ wait_for_children(srv, client->pid);
+
+
/* Wait for events or signals */
count = epoll_wait(srv->epoll_fd,
ee, ARRAY_LENGTH(ee), -1);
diff --git a/src/wth-receiver-seat.c b/src/wth-receiver-seat.c
index f4b4886..f137e01 100644
--- a/src/wth-receiver-seat.c
+++ b/src/wth-receiver-seat.c
@@ -35,9 +35,9 @@ waltham_touch_down(struct window *window, uint32_t serial,
uint32_t time, int32_t id,
wl_fixed_t x_w, wl_fixed_t y_w)
{
- struct surface *surface = window->receiver_surf;
struct seat *seat = window->receiver_seat;
struct touch *touch = seat->touch;
+ struct surface *surface = window->receiver_surf;
if (!touch) {
fprintf(stderr, "We do not have touch device!\n");
@@ -45,7 +45,6 @@ waltham_touch_down(struct window *window, uint32_t serial,
}
if (touch->obj) {
- fprintf(stdout, "waltham_touch_down() sending touch_down\n");
wthp_touch_send_down(touch->obj, serial, time, surface->obj, id, x_w, y_w);
}
return;
@@ -64,7 +63,6 @@ waltham_touch_up(struct window *window, uint32_t serial,
}
if (touch->obj) {
- fprintf(stdout, "waltham_touch_motion() sending touch_up\n");
wthp_touch_send_up(touch->obj, serial, time, id);
}
return;
@@ -83,7 +81,6 @@ waltham_touch_motion(struct window *window, uint32_t time,
}
if (touch->obj) {
- fprintf(stdout, "waltham_touch_motion() sending touch_motion\n");
wthp_touch_send_motion(touch->obj, time, id, x_w, y_w);
}
}
@@ -100,7 +97,6 @@ waltham_touch_frame(struct window *window)
}
if (touch->obj) {
- fprintf(stdout, "waltham_touch_frame() sending frame\n");
wthp_touch_send_frame(touch->obj);
}
}
@@ -353,9 +349,6 @@ client_bind_seat(struct client *c, struct wthp_seat *obj)
seat->client = c;
wl_list_insert(&c->seat_list, &seat->link);
- fprintf(stdout, "wthp_seat object=%p and seat=%p\n",obj,seat);
wthp_seat_set_interface(obj, &seat_implementation, seat);
-
- fprintf(stdout, "client %p bound wthp_seat\n", c);
seat_send_updated_caps(seat);
}