[svn r833] - Restored working version of gmyth_monitor_handler.c trunk
authormorphbr
Tue Aug 28 08:16:13 2007 +0100 (2007-08-28)
branchtrunk
changeset 82730368d31696e
parent 826 e0152712fd4f
child 828 2061bf4c30c7
[svn r833] - Restored working version of gmyth_monitor_handler.c
- Patch on gmyth-cat by Renato Filho
gmyth/samples/gmyth_cat.c
gmyth/src/gmyth_monitor_handler.c
gmyth/src/gmyth_monitor_handler.h
     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);