1.1 --- a/gmyth/samples/gmyth_cat.c Thu Aug 23 22:45:15 2007 +0100
1.2 +++ b/gmyth/samples/gmyth_cat.c Tue Aug 28 08:16:13 2007 +0100
1.3 @@ -200,7 +200,7 @@
1.4 (GByteArray *) array, 64000, TRUE)) == GMYTH_FILE_READ_OK) ||
1.5 file_transf_ret == GMYTH_FILE_READ_NEXT_PROG_CHAIN) {
1.6
1.7 - fwrite(array->data, array->len, 1, stdout);
1.8 + fwrite(array->data, sizeof(gpointer), array->len, stdout);
1.9 fflush(stdout);
1.10 g_array_remove_range(array, 0, array->len);
1.11
2.1 --- a/gmyth/src/gmyth_monitor_handler.c Thu Aug 23 22:45:15 2007 +0100
2.2 +++ b/gmyth/src/gmyth_monitor_handler.c Tue Aug 28 08:16:13 2007 +0100
2.3 @@ -70,9 +70,7 @@
2.4 #define GMYTHTV_ENABLE_DEBUG 1
2.5 #endif
2.6
2.7 -gboolean gmyth_monitor_handler_listener (GIOChannel *io_channel,
2.8 - GIOCondition condition,
2.9 - gpointer data);
2.10 +gpointer gmyth_monitor_handler_listener(gpointer data);
2.11
2.12 static void gmyth_monitor_handler_default_listener(GMythMonitorHandler
2.13 * monitor,
2.14 @@ -94,10 +92,51 @@
2.15
2.16 void gmyth_monitor_handler_close(GMythMonitorHandler * monitor);
2.17
2.18 -G_DEFINE_TYPE(GMythMonitorHandler, gmyth_monitor_handler, G_TYPE_OBJECT);
2.19 +G_DEFINE_TYPE(GMythMonitorHandler, gmyth_monitor_handler, G_TYPE_OBJECT)
2.20 + static void
2.21
2.22 -static void
2.23 -gmyth_monitor_handler_class_init(GMythMonitorHandlerClass * klass)
2.24 +
2.25 +
2.26 +
2.27 +
2.28 +
2.29 +
2.30 +
2.31 +
2.32 +
2.33 +
2.34 +
2.35 +
2.36 +
2.37 +
2.38 +
2.39 +
2.40 +
2.41 +
2.42 +
2.43 +
2.44 +
2.45 +
2.46 +
2.47 +
2.48 +
2.49 +
2.50 +
2.51 +
2.52 +
2.53 +
2.54 +
2.55 +
2.56 +
2.57 +
2.58 +
2.59 +
2.60 +
2.61 +
2.62 +
2.63 +
2.64 +
2.65 + gmyth_monitor_handler_class_init(GMythMonitorHandlerClass * klass)
2.66 {
2.67 GObjectClass *gobject_class;
2.68 GMythMonitorHandlerClass *gmonitor_class;
2.69 @@ -130,11 +169,23 @@
2.70 monitor->hostname = NULL;
2.71 monitor->port = 0;
2.72 monitor->actual_index = 0;
2.73 +
2.74 monitor->allow_msgs_listener = FALSE;
2.75 +
2.76 + /*
2.77 + * monitor->backend_msgs = g_hash_table_new( g_int_hash, g_int_equal
2.78 + * );
2.79 + */
2.80 +
2.81 /*
2.82 * it is used for signalizing the event socket consumer thread
2.83 */
2.84 monitor->mutex = g_mutex_new();
2.85 +
2.86 + monitor->th = NULL;
2.87 +
2.88 + monitor->gmyth_monitor_handler_listener =
2.89 + gmyth_monitor_handler_listener;
2.90 }
2.91
2.92 static void
2.93 @@ -146,9 +197,14 @@
2.94
2.95 monitor->allow_msgs_listener = FALSE;
2.96
2.97 - if (monitor->io_source != 0) {
2.98 - g_source_remove (monitor->io_source);
2.99 - monitor->io_source = 0;
2.100 + if (monitor->th != NULL) {
2.101 + gboolean *ret = (gboolean *) g_thread_join(monitor->th);
2.102 +
2.103 + if (*ret == FALSE)
2.104 + gmyth_debug("Error closing GThread listener socket!");
2.105 + else
2.106 + gmyth_debug("Closed GThread listener socket.");
2.107 + // g_object_unref( monitor->th );
2.108 }
2.109
2.110 /*
2.111 @@ -170,7 +226,6 @@
2.112 monitor->hostname = NULL;
2.113 }
2.114
2.115 -
2.116 if (monitor->backend_msgs != NULL) {
2.117 g_hash_table_destroy(monitor->backend_msgs);
2.118 monitor->backend_msgs = NULL;
2.119 @@ -181,7 +236,6 @@
2.120 * io_watcher_cond = NULL; }
2.121 */
2.122
2.123 -
2.124 G_OBJECT_CLASS(gmyth_monitor_handler_parent_class)->dispose(object);
2.125 }
2.126
2.127 @@ -299,22 +353,30 @@
2.128 gmyth_debug("Monitor event socket --- hostname: %s, port %d\n",
2.129 monitor->hostname, monitor->port);
2.130
2.131 - if (monitor->event_sock != NULL) {
2.132 + if (NULL != monitor->event_sock) {
2.133 g_object_unref(monitor->event_sock);
2.134 monitor->event_sock = NULL;
2.135 }
2.136
2.137 /*
2.138 - * configure the event socket
2.139 + * configure the event socket
2.140 */
2.141 - if (!gmyth_connect_to_backend_monitor(monitor)) {
2.142 - gmyth_debug("Connection to backend failed (Event Socket)!");
2.143 - ret = FALSE;
2.144 + if (NULL == monitor->event_sock) {
2.145 + if (!gmyth_connect_to_backend_monitor(monitor)) {
2.146 + gmyth_debug("Connection to backend failed (Event Socket)!");
2.147 + ret = FALSE;
2.148 + } else {
2.149 + gmyth_debug
2.150 + ("Remote monitor event socket had been succesfully created. (io_fd == %d)\n",
2.151 + g_io_channel_unix_get_fd(monitor->event_sock->sd_io_ch));
2.152 + }
2.153 } else {
2.154 - gmyth_debug ("Remote monitor event socket had been succesfully create");
2.155 + gmyth_debug
2.156 + ("ASSERT ERROR: Remote monitor event socket is not NULL at the setup...\n");
2.157 }
2.158
2.159 return ret;
2.160 +
2.161 }
2.162
2.163 /**
2.164 @@ -431,73 +493,122 @@
2.165 * @return Pointer to a gboolean <code>true</code> value, if the data was
2.166 * successfully read.
2.167 */
2.168 -gboolean
2.169 -gmyth_monitor_handler_listener (GIOChannel *io_channel,
2.170 - GIOCondition io_cond,
2.171 - gpointer data)
2.172 +gpointer
2.173 +gmyth_monitor_handler_listener(gpointer data)
2.174 {
2.175 - GMythMonitorHandler *monitor;
2.176 + GMythMonitorHandler *monitor = (GMythMonitorHandler *) data;
2.177 guint recv = 0;
2.178 + gboolean *ret = g_new0(gboolean, 1);
2.179 gsize len = 0;
2.180 - GMythStringList *strlist = NULL;
2.181 - gint bytes_sent = 0;
2.182 + GIOChannel *io_channel = monitor->event_sock->sd_io_ch;
2.183 + GIOCondition io_cond =
2.184 + g_io_channel_get_buffer_condition(io_channel);
2.185 + static guint count = 0;
2.186
2.187 - monitor = (GMythMonitorHandler *) data;
2.188 + *ret = TRUE;
2.189
2.190 gmyth_debug("Entering MONITOR handler listener...");
2.191
2.192 myth_control_acquire_context(monitor, TRUE);
2.193
2.194 - if (((io_cond & G_IO_HUP) != 0) ||
2.195 - ((io_cond & G_IO_ERR) != 0)) {
2.196 + if ((io_cond & G_IO_HUP) != 0) {
2.197 + *ret = FALSE;
2.198 goto clean_up;
2.199 }
2.200
2.201 + GMythStringList *strlist = NULL;
2.202
2.203 - gmyth_debug("%d - Listening on Monitor socket...!\n", count);
2.204 - strlist = gmyth_string_list_new();
2.205 -
2.206 - len = gmyth_socket_read_stringlist(monitor->event_sock, strlist);
2.207 - if ((len > 0) && strlist != NULL && gmyth_string_list_length(strlist) > 0) {
2.208 - gchar *back_msg_action;
2.209 - gint msg_type;
2.210 -
2.211 - bytes_sent = gmyth_string_list_get_int(strlist, 0);
2.212 - // on backend error
2.213 - gmyth_debug ("received data buffer from IO event channel... %d strings gone!\n", len);
2.214 - recv += len;
2.215 -
2.216 - /*
2.217 - * debug purpose: prints out all the string list
2.218 - * elements
2.219 - */
2.220 - g_list_foreach(strlist->glist,
2.221 - (GFunc) gmyth_monitor_handler_print,
2.222 - NULL);
2.223 -
2.224 - back_msg_action = g_new0(gchar, 1);
2.225 - msg_type = gmyth_monitor_handler_is_backend_message(monitor,
2.226 - strlist,
2.227 - &back_msg_action);
2.228 -
2.229 - if (msg_type != GMYTH_BACKEND_NO_MESSAGE) {
2.230 - g_signal_emit(monitor,
2.231 - GMYTH_MONITOR_HANDLER_GET_CLASS(monitor)->backend_events_handler_signal_id,
2.232 - 0, msg_type, back_msg_action);
2.233 - }
2.234 -
2.235 - if (back_msg_action != NULL)
2.236 - g_free(back_msg_action);
2.237 -
2.238 - g_object_unref(strlist);
2.239 + if (NULL == io_channel) {
2.240 + gmyth_debug("Monitor socket is NULL! (GIOChannel)");
2.241 + *ret = FALSE;
2.242 + goto clean_up;
2.243 }
2.244
2.245 -clean_up:
2.246 + while (monitor->allow_msgs_listener) {
2.247 + ++count;
2.248 +
2.249 + gmyth_debug("%d - Listening on Monitor socket...!\n", count);
2.250 +
2.251 + do {
2.252 +
2.253 + gint bytes_sent = 0;
2.254 +
2.255 + strlist = gmyth_string_list_new();
2.256 +
2.257 + if (monitor->event_sock != NULL) {
2.258 +
2.259 + len =
2.260 + gmyth_socket_read_stringlist(monitor->event_sock,
2.261 + strlist);
2.262 +
2.263 + if ((len > 0) && strlist != NULL
2.264 + && gmyth_string_list_length(strlist) > 0) {
2.265 + bytes_sent = gmyth_string_list_get_int(strlist, 0); // -1
2.266 + //
2.267 + //
2.268 + // on
2.269 + // backend
2.270 + // error
2.271 +
2.272 + gmyth_debug
2.273 + ("[%s] MONITOR: received data buffer from IO event channel... %d strings gone!\n",
2.274 + __FUNCTION__, len);
2.275 +
2.276 + recv += len;
2.277 +
2.278 + /*
2.279 + * debug purpose: prints out all the string list
2.280 + * elements
2.281 + */
2.282 + g_list_foreach(strlist->glist,
2.283 + (GFunc) gmyth_monitor_handler_print,
2.284 + NULL);
2.285 +
2.286 + gchar *back_msg_action = g_new0(gchar, 1);
2.287 + gint msg_type =
2.288 + gmyth_monitor_handler_is_backend_message(monitor,
2.289 + strlist,
2.290 + &back_msg_action);
2.291 +
2.292 + if (monitor != NULL
2.293 + && msg_type != GMYTH_BACKEND_NO_MESSAGE)
2.294 + g_signal_emit(monitor, GMYTH_MONITOR_HANDLER_GET_CLASS(monitor)->backend_events_handler_signal_id, 0, /* details
2.295 + */
2.296 + msg_type, back_msg_action);
2.297 +
2.298 + if (back_msg_action != NULL)
2.299 + g_free(back_msg_action);
2.300 +
2.301 + }
2.302 +
2.303 + }
2.304 +
2.305 + if (strlist != NULL) {
2.306 + g_object_unref(strlist);
2.307 + strlist = NULL;
2.308 + }
2.309 +
2.310 + io_cond = g_io_channel_get_buffer_condition(io_channel);
2.311 +
2.312 + g_usleep(500);
2.313 +
2.314 + }
2.315 + while (recv <= 0 && ((io_cond & G_IO_HUP) == 0));
2.316 +
2.317 + gmyth_debug("\tMONITOR EVENT: Read %d bytes\n", recv);
2.318 +
2.319 + } /* main GThread while */
2.320 +
2.321 + clean_up:
2.322 myth_control_release_context(monitor);
2.323 - return TRUE;
2.324 +
2.325 + g_thread_exit(ret);
2.326 +
2.327 + return (gpointer) ret;
2.328 +
2.329 }
2.330
2.331 -/**
2.332 +/**
2.333 * Opens connection events' socket the the Monitor socket on
2.334 * MythTV backend server.
2.335 *
2.336 @@ -505,7 +616,7 @@
2.337 *
2.338 * @return <code>true</code>, if the socket was successfully opened.
2.339 */
2.340 -static gboolean
2.341 +static gboolean
2.342 gmyth_connect_to_backend_monitor(GMythMonitorHandler * monitor)
2.343 {
2.344 gboolean ret = TRUE;
2.345 @@ -514,7 +625,7 @@
2.346
2.347 /*
2.348 * Connects the socket, send Mythtv ANN Monitor and verify Mythtv
2.349 - * protocol version
2.350 + * protocol version
2.351 */
2.352 if (!gmyth_socket_connect_to_backend_events(monitor->event_sock,
2.353 monitor->hostname,
2.354 @@ -527,38 +638,52 @@
2.355 return ret;
2.356 }
2.357
2.358 -/**
2.359 +/**
2.360 * Opens connection the the Monitor socket on MythTV backend server,
2.361 * where all status messages are notified to the client.
2.362 - *
2.363 + *
2.364 * @param monitor The GMythMonitorHandler instance.
2.365 * @param channel The GIOChannel instance to the Monitor socket.
2.366 - *
2.367 + *
2.368 * @return Pointer to the boolean value, and it is <code>true</code> only if the
2.369 - * GMythMonitorHandler could be configured.
2.370 + * GMythMonitorHandler could be configured.
2.371 */
2.372 -static gboolean
2.373 +static gboolean
2.374 gmyth_monitor_handler_setup(GMythMonitorHandler * monitor,
2.375 GIOChannel * channel)
2.376 {
2.377 - gboolean ret = TRUE;
2.378 + gboolean ret = TRUE;
2.379
2.380 if (channel != NULL) {
2.381 monitor->allow_msgs_listener = TRUE;
2.382 - monitor->io_source = g_io_add_watch (channel, G_IO_IN | G_IO_ERR | G_IO_HUP,
2.383 - gmyth_monitor_handler_listener,
2.384 - monitor);
2.385 +
2.386 + monitor->th =
2.387 + g_thread_create((GThreadFunc) gmyth_monitor_handler_listener,
2.388 + monitor, TRUE, NULL);
2.389 + gmyth_debug("MONITOR GThread created!");
2.390 } else {
2.391 ret = FALSE;
2.392 + goto cleanup;
2.393 }
2.394 +
2.395 + if (NULL == monitor->th) {
2.396 + gmyth_debug
2.397 + ("[%s] Error adding GThread listener function to the IO control channel!\n",
2.398 + __FUNCTION__);
2.399 + ret = FALSE;
2.400 + goto cleanup;
2.401 + }
2.402 +
2.403 + cleanup:
2.404 +
2.405 return ret;
2.406 }
2.407
2.408 -/**
2.409 +/**
2.410 * Starts the MonitorHandler thread to the GIOWatcher.
2.411 - *
2.412 + *
2.413 * @param monitor The GMythMonitorHandler instance.
2.414 - *
2.415 + *
2.416 * @return <code>true</code>, if the MonitorHandler was started.
2.417 */
2.418 gboolean
3.1 --- a/gmyth/src/gmyth_monitor_handler.h Thu Aug 23 22:45:15 2007 +0100
3.2 +++ b/gmyth/src/gmyth_monitor_handler.h Tue Aug 28 08:16:13 2007 +0100
3.3 @@ -63,12 +63,12 @@
3.4 GObjectClass parent_class;
3.5
3.6 /*
3.7 - * callbacks
3.8 + * callbacks
3.9 */
3.10 guint backend_events_handler_signal_id;
3.11
3.12 /*
3.13 - * signal default handlers
3.14 + * signal default handlers
3.15 */
3.16 void (*backend_events_handler) (GMythMonitorHandler *
3.17 monitor, gint msg_code,
3.18 @@ -88,7 +88,13 @@
3.19 */
3.20 GMythSocket *event_sock;
3.21
3.22 - //gpointer(*gmyth_monitor_handler_listener) (gpointer data);
3.23 +
3.24 +
3.25 +
3.26 +
3.27 +
3.28 +
3.29 + gpointer(*gmyth_monitor_handler_listener) (gpointer data);
3.30
3.31 gchar *hostname;
3.32 gint port;
3.33 @@ -103,7 +109,9 @@
3.34 GHashTable *backend_msgs;
3.35
3.36 GMutex *mutex;
3.37 - guint io_source;
3.38 +
3.39 + GThread *th;
3.40 +
3.41 };
3.42
3.43 GType gmyth_monitor_handler_get_type(void);