gmyth/src/gmyth_monitor_handler.c
author renatofilho
Tue Jun 19 22:01:13 2007 +0100 (2007-06-19)
branchtrunk
changeset 755 4b5efa290285
parent 750 312d6bc514f3
child 817 888b9724f601
permissions -rw-r--r--
[svn r761] create function to get recorded inf; fixe some headers indent
     1 /**
     2  * GMyth Library
     3  *
     4  * @file gmyth/gmyth_monitor_handler.c
     5  * 
     6  * @brief <p> GMythMonitorHandler deals with the streaming media events remote/local
     7  * that are sent to the MythTV frontend.
     8  *
     9  * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
    10  * @author Rosfran Lins Borges <rosfran.borges@indt.org.br>
    11  *
    12  * 
    13  * This program is free software; you can redistribute it and/or modify
    14  * it under the terms of the GNU Lesser General Public License as published by
    15  * the Free Software Foundation; either version 2 of the License, or
    16  * (at your option) any later version.
    17  *
    18  * This program is distributed in the hope that it will be useful,
    19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    21  * GNU General Public License for more details.
    22  *
    23  * You should have received a copy of the GNU Lesser General Public License
    24  * along with this program; if not, write to the Free Software
    25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    26  *
    27  * GStreamer MythTV plug-in properties:
    28  * - location (backend server hostname/URL) [ex.: myth://192.168.1.73:28722/1000_1092091.nuv]
    29  * - path (qurl - remote file to be opened)
    30  * - port number *   
    31  */
    32 
    33 #ifdef HAVE_CONFIG_H
    34 #include "config.h"
    35 #endif
    36 
    37 #include <unistd.h>
    38 #include <glib.h>
    39 #include <arpa/inet.h>
    40 #include <sys/types.h>
    41 #include <sys/socket.h>
    42 #include <netdb.h>
    43 #include <errno.h>
    44 #include <stdlib.h>
    45 #include <assert.h>
    46 
    47 #include "gmyth_marshal.h"
    48 
    49 #include "gmyth_monitor_handler.h"
    50 #include "gmyth_debug.h"
    51 
    52 #define GMYTHTV_QUERY_HEADER		"QUERY_FILETRANSFER "
    53 
    54 #define GMYTHTV_VERSION							30
    55 
    56 #define GMYTHTV_TRANSFER_MAX_WAITS	700
    57 
    58 #define GMYTHTV_BUFFER_SIZE					8*1024
    59 
    60 #ifdef GMYTHTV_ENABLE_DEBUG
    61 #define GMYTHTV_ENABLE_DEBUG				1
    62 #else
    63 #undef GMYTHTV_ENABLE_DEBUG
    64 #endif
    65 
    66 /*
    67  * this NDEBUG is to maintain compatibility with GMyth library 
    68  */
    69 #ifndef NDEBUG
    70 #define GMYTHTV_ENABLE_DEBUG				1
    71 #endif
    72 
    73 gpointer        gmyth_monitor_handler_listener(gpointer data);
    74 
    75 static void     gmyth_monitor_handler_default_listener(GMythMonitorHandler
    76                                                        * monitor,
    77                                                        gint msg_code,
    78                                                        gchar * message);
    79 
    80 static void     gmyth_monitor_handler_class_init(GMythMonitorHandlerClass *
    81                                                  klass);
    82 static void     gmyth_monitor_handler_init(GMythMonitorHandler * object);
    83 
    84 static void     gmyth_monitor_handler_dispose(GObject * object);
    85 static void     gmyth_monitor_handler_finalize(GObject * object);
    86 
    87 static gboolean gmyth_connect_to_backend_monitor(GMythMonitorHandler *
    88                                                  monitor);
    89 
    90 static gboolean gmyth_monitor_handler_setup(GMythMonitorHandler * monitor,
    91                                             GIOChannel * channel);
    92 
    93 void            gmyth_monitor_handler_close(GMythMonitorHandler * monitor);
    94 
    95 G_DEFINE_TYPE(GMythMonitorHandler, gmyth_monitor_handler, G_TYPE_OBJECT)
    96     static void
    97 
    98 
    99 
   100 
   101 
   102 
   103 
   104 
   105 
   106 
   107 
   108 
   109 
   110 
   111 
   112 
   113 
   114 
   115 
   116 
   117 
   118 
   119 
   120 
   121 
   122 
   123 
   124 
   125      
   126         
   127         
   128         
   129         
   130         
   131         
   132         
   133         
   134         
   135         
   136         
   137         
   138         
   139          gmyth_monitor_handler_class_init(GMythMonitorHandlerClass * klass)
   140 {
   141     GObjectClass   *gobject_class;
   142     GMythMonitorHandlerClass *gmonitor_class;
   143 
   144     gobject_class = (GObjectClass *) klass;
   145     gmonitor_class = (GMythMonitorHandlerClass *) gobject_class;
   146 
   147     gobject_class->dispose = gmyth_monitor_handler_dispose;
   148     gobject_class->finalize = gmyth_monitor_handler_finalize;
   149 
   150     gmonitor_class->backend_events_handler_signal_id =
   151         g_signal_new("backend-events-handler",
   152                      G_TYPE_FROM_CLASS(gmonitor_class),
   153                      G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE |
   154                      G_SIGNAL_NO_HOOKS, 0, NULL, NULL,
   155                      gmyth_marshal_VOID__INT_STRING, G_TYPE_NONE, 2,
   156                      G_TYPE_INT, G_TYPE_STRING);
   157 
   158     gmonitor_class->backend_events_handler =
   159         gmyth_monitor_handler_default_listener;
   160 
   161 }
   162 
   163 static void
   164 gmyth_monitor_handler_init(GMythMonitorHandler * monitor)
   165 {
   166     g_return_if_fail(monitor != NULL);
   167 
   168     monitor->event_sock = NULL;
   169     monitor->hostname = NULL;
   170     monitor->port = 0;
   171     monitor->actual_index = 0;
   172 
   173     monitor->allow_msgs_listener = FALSE;
   174 
   175     /*
   176      * monitor->backend_msgs = g_hash_table_new( g_int_hash, g_int_equal
   177      * ); 
   178      */
   179 
   180     /*
   181      * it is used for signalizing the event socket consumer thread 
   182      */
   183     monitor->mutex = g_mutex_new();
   184 
   185     monitor->th = NULL;
   186 
   187     monitor->gmyth_monitor_handler_listener =
   188         gmyth_monitor_handler_listener;
   189 }
   190 
   191 static void
   192 gmyth_monitor_handler_dispose(GObject * object)
   193 {
   194     GMythMonitorHandler *monitor = GMYTH_MONITOR_HANDLER(object);
   195 
   196     gmyth_monitor_handler_close(monitor);
   197 
   198     monitor->allow_msgs_listener = FALSE;
   199 
   200     if (monitor->th != NULL) {
   201         gboolean       *ret = (gboolean *) g_thread_join(monitor->th);
   202 
   203         if (*ret == FALSE)
   204             gmyth_debug("Error closing GThread listener socket!");
   205         else
   206             gmyth_debug("Closed GThread listener socket.");
   207         // g_object_unref( monitor->th );
   208     }
   209 
   210     /*
   211      * mutex to control access to the event socket consumer thread 
   212      */
   213     if (monitor->mutex != NULL) {
   214         // g_mutex_unlock( monitor->mutex );
   215         g_mutex_free(monitor->mutex);
   216         monitor->mutex = NULL;
   217     }
   218 
   219     if (monitor->event_sock != NULL) {
   220         g_object_unref(monitor->event_sock);
   221         monitor->event_sock = NULL;
   222     }
   223 
   224     if (monitor->hostname != NULL) {
   225         g_free(monitor->hostname);
   226         monitor->hostname = NULL;
   227     }
   228 
   229     if (monitor->backend_msgs != NULL) {
   230         g_hash_table_destroy(monitor->backend_msgs);
   231         monitor->backend_msgs = NULL;
   232     }
   233 
   234     /*
   235      * if ( io_watcher_cond != NULL ) { g_cond_free( io_watcher_cond );
   236      * io_watcher_cond = NULL; } 
   237      */
   238 
   239     G_OBJECT_CLASS(gmyth_monitor_handler_parent_class)->dispose(object);
   240 }
   241 
   242 static void
   243 gmyth_monitor_handler_finalize(GObject * object)
   244 {
   245     g_signal_handlers_destroy(object);
   246 
   247     G_OBJECT_CLASS(gmyth_monitor_handler_parent_class)->finalize(object);
   248 }
   249 
   250 /** 
   251  * Creates a new instance of GMyth Monitor Handler.
   252  * 
   253  * @return a new instance of the Monitor Handler. 
   254  */
   255 GMythMonitorHandler *
   256 gmyth_monitor_handler_new(void)
   257 {
   258     GMythMonitorHandler *monitor =
   259         GMYTH_MONITOR_HANDLER(g_object_new
   260                               (GMYTH_MONITOR_HANDLER_TYPE, FALSE));
   261 
   262     return monitor;
   263 }
   264 
   265 /** 
   266  * Acquire the mutex to have access to the IO Watcher listener.
   267  * 
   268  * @param monitor The GMythMonitorHandler instance.
   269  * @param do_wait Tells the IO Watcher to wait on the GCond. (obsolete)
   270  * 
   271  * @return <code>true</code>, if the access to IO Watcher was acquired. 
   272  */
   273 static          gboolean
   274 myth_control_acquire_context(GMythMonitorHandler * monitor,
   275                              gboolean do_wait)
   276 {
   277 
   278     gboolean        ret = TRUE;
   279 
   280     g_mutex_lock(monitor->mutex);
   281 
   282     return ret;
   283 
   284 }
   285 
   286 /** 
   287  * Release the mutex to have access to the IO Watcher listener.
   288  * 
   289  * @param monitor The GMythMonitorHandler instance.
   290  * 
   291  * @return <code>true</code>, if the access to IO Watcher was released. 
   292  */
   293 static          gboolean
   294 myth_control_release_context(GMythMonitorHandler * monitor)
   295 {
   296 
   297     gboolean        ret = TRUE;
   298 
   299     g_mutex_unlock(monitor->mutex);
   300 
   301     return ret;
   302 }
   303 
   304 void
   305 gmyth_monitor_handler_close(GMythMonitorHandler * monitor)
   306 {
   307     monitor->allow_msgs_listener = FALSE;
   308 
   309 #if 0
   310     if (monitor->monitor_th != NULL) {
   311         g_thread_pool_free(monitor->monitor_th, TRUE, FALSE);
   312         // g_thread_exit( monitor->monitor_th );
   313         /*
   314          * if ( monitor->monitor_th != NULL ) g_object_unref(
   315          * monitor->monitor_th ); 
   316          */
   317         monitor->monitor_th = NULL;
   318     }
   319 
   320     if (monitor->event_sock != NULL) {
   321         gmyth_socket_close_connection(monitor->event_sock);
   322     }
   323 #endif
   324 
   325 }
   326 
   327 /** 
   328  * Opens connection the the Monitor socket on MythTV backend server,
   329  * where all status messages are notified to the client.
   330  * 
   331  * @param monitor The GMythMonitorHandler instance.
   332  * @param hostname The remote host name of the MythTV backend server.
   333  * @param port The remote port number of the MythTV backend server.
   334  * 
   335  * @return <code>true</code>, if the connection was successfully opened.
   336  */
   337 gboolean
   338 gmyth_monitor_handler_open(GMythMonitorHandler * monitor,
   339                            const gchar * hostname, gint port)
   340 {
   341     gboolean        ret = TRUE;
   342 
   343     g_return_val_if_fail(hostname != NULL, FALSE);
   344 
   345     if (monitor->hostname != NULL) {
   346         g_free(monitor->hostname);
   347         monitor->hostname = NULL;
   348     }
   349 
   350     monitor->hostname = g_strdup(hostname);
   351     monitor->port = port;
   352 
   353     gmyth_debug("Monitor event socket --- hostname: %s, port %d\n",
   354                 monitor->hostname, monitor->port);
   355 
   356     if (NULL != monitor->event_sock) {
   357         g_object_unref(monitor->event_sock);
   358         monitor->event_sock = NULL;
   359     }
   360 
   361     /*
   362      * configure the event socket 
   363      */
   364     if (NULL == monitor->event_sock) {
   365         if (!gmyth_connect_to_backend_monitor(monitor)) {
   366             gmyth_debug("Connection to backend failed (Event Socket)!");
   367             ret = FALSE;
   368         } else {
   369             gmyth_debug
   370                 ("Remote monitor event socket had been succesfully created. (io_fd == %d)\n",
   371                  g_io_channel_unix_get_fd(monitor->event_sock->sd_io_ch));
   372         }
   373     } else {
   374         gmyth_debug
   375             ("ASSERT ERROR: Remote monitor event socket is not NULL at the setup...\n");
   376     }
   377 
   378     return ret;
   379 
   380 }
   381 
   382 /** 
   383  * Reads the data got from the connection to the Monitor socket,
   384  * and looks for some important status messages.
   385  * 
   386  * @param monitor The GMythMonitorHandler instance.
   387  * @param strlist The GMythStringList instance got from the Monitor remote socket.
   388  * @param back_msg_action A string pointer to the status message detailed description.
   389  * 
   390  * @return The backend status message code ID.
   391  */
   392 static          gint
   393 gmyth_monitor_handler_is_backend_message(GMythMonitorHandler * monitor,
   394                                          GMythStringList * strlist,
   395                                          gchar ** back_msg_action)
   396 {
   397     gint            msg_type = GMYTH_BACKEND_NO_MESSAGE;
   398     GString        *back_msg = NULL;
   399 
   400     if (gmyth_string_list_length(strlist) > 0) {
   401 
   402         back_msg = gmyth_string_list_get_string(strlist, 0);
   403         if (back_msg != NULL && back_msg->str != NULL &&
   404             strstr(back_msg->str, "BACKEND") != NULL) {
   405             gmyth_debug("MONITOR HANDLER - Received backend message = %s",
   406                         back_msg->str);
   407             *back_msg_action =
   408                 gmyth_string_list_get_char_array(strlist, 1);
   409 
   410             if (back_msg_action != NULL) {
   411 
   412                 if (g_strstr_len
   413                     (*back_msg_action, strlen(*back_msg_action),
   414                      "LIVETV_CHAIN")
   415                     || g_strstr_len(*back_msg_action,
   416                                     strlen(*back_msg_action),
   417                                     "RECORDING_LIST_CHANGE")
   418                     || g_strstr_len(*back_msg_action,
   419                                     strlen(*back_msg_action),
   420                                     "SCHEDULE_CHANGE")
   421                     || g_strstr_len(*back_msg_action,
   422                                     strlen(*back_msg_action),
   423                                     "LIVETV_WATCH")) {
   424                     gmyth_debug
   425                         ("MONITOR: message type == GMYTH_BACKEND_PROGRAM_INFO_CHANGED, msg = %s",
   426                          *back_msg_action);
   427                     msg_type = GMYTH_BACKEND_PROGRAM_INFO_CHANGED;
   428                 } else if (g_strstr_len
   429                            (*back_msg_action, strlen(*back_msg_action),
   430                             "DONE_RECORDING")) {
   431                     gmyth_debug
   432                         ("MONITOR: message type == GMYTH_BACKEND_DONE_RECORDING, msg = %s",
   433                          *back_msg_action);
   434                     msg_type = GMYTH_BACKEND_DONE_RECORDING;
   435                 } else if (g_strstr_len
   436                            (*back_msg_action, strlen(*back_msg_action),
   437                             "QUIT")) {
   438                     gmyth_debug
   439                         ("MONITOR: message type == GMYTH_BACKEND_STOP_LIVETV, msg = %s",
   440                          *back_msg_action);
   441                     msg_type = GMYTH_BACKEND_STOP_LIVETV;
   442                 }
   443 
   444                 /*
   445                  * g_hash_table_insert ( monitor->backend_msgs,
   446                  * &(monitor->actual_index), *back_msg_action ); 
   447                  */
   448 
   449             }
   450             /*
   451              * if 
   452              */
   453         }
   454         /*
   455          * if 
   456          */
   457         if (back_msg != NULL) {
   458             g_string_free(back_msg, TRUE);
   459             back_msg = NULL;
   460         }
   461 
   462     }                           /* if - Does Monitor got any message from
   463                                  * * * backend? */
   464     else {
   465         *back_msg_action = g_strdup("");
   466     }
   467 
   468     return msg_type;
   469 
   470 }
   471 
   472 static void
   473 gmyth_monitor_handler_default_listener(GMythMonitorHandler * monitor,
   474                                        gint msg_code, gchar * message)
   475 {
   476     // assert( message!= NULL ); 
   477     gmyth_debug("DEFAULT Signal handler ( msg = %s, code = %d )\n",
   478                 message, msg_code);
   479 }
   480 
   481 static void
   482 gmyth_monitor_handler_print(GString * str, gpointer ptr)
   483 {
   484     gmyth_debug("Backend message event: %s --- ", str->str);
   485 }
   486 
   487 /** 
   488  * Opens connection the the Monitor socket on MythTV backend server,
   489  * where all status messages are notified to the client.
   490  * 
   491  * @param data Pointer to the GMythMonitorHandler.
   492  * 
   493  * @return Pointer to a gboolean <code>true</code> value, if the data was 
   494  * 	successfully read.
   495  */
   496 gpointer
   497 gmyth_monitor_handler_listener(gpointer data)
   498 {
   499     GMythMonitorHandler *monitor = (GMythMonitorHandler *) data;
   500     guint           recv = 0;
   501     gboolean       *ret = g_new0(gboolean, 1);
   502     gsize           len = 0;
   503     GIOChannel     *io_channel = monitor->event_sock->sd_io_ch;
   504     GIOCondition    io_cond =
   505         g_io_channel_get_buffer_condition(io_channel);
   506     static guint    count = 0;
   507 
   508     *ret = TRUE;
   509 
   510     gmyth_debug("Entering MONITOR handler listener...");
   511 
   512     myth_control_acquire_context(monitor, TRUE);
   513 
   514     if ((io_cond & G_IO_HUP) != 0) {
   515         *ret = FALSE;
   516         goto clean_up;
   517     }
   518 
   519     GMythStringList *strlist = NULL;
   520 
   521     if (NULL == io_channel) {
   522         gmyth_debug("Monitor socket is NULL! (GIOChannel)");
   523         *ret = FALSE;
   524         goto clean_up;
   525     }
   526 
   527     while (monitor->allow_msgs_listener) {
   528         ++count;
   529 
   530         gmyth_debug("%d - Listening on Monitor socket...!\n", count);
   531 
   532         do {
   533 
   534             gint            bytes_sent = 0;
   535 
   536             strlist = gmyth_string_list_new();
   537 
   538             if (monitor->event_sock != NULL) {
   539 
   540                 len =
   541                     gmyth_socket_read_stringlist(monitor->event_sock,
   542                                                  strlist);
   543 
   544                 if ((len > 0) && strlist != NULL
   545                     && gmyth_string_list_length(strlist) > 0) {
   546                     bytes_sent = gmyth_string_list_get_int(strlist, 0); // -1 
   547                                                                         // 
   548                     // 
   549                     // on 
   550                     // backend 
   551                     // error
   552 
   553                     gmyth_debug
   554                         ("[%s] MONITOR: received data buffer from IO event channel... %d strings gone!\n",
   555                          __FUNCTION__, len);
   556 
   557                     recv += len;
   558 
   559                     /*
   560                      * debug purpose: prints out all the string list
   561                      * elements 
   562                      */
   563                     g_list_foreach(strlist->glist,
   564                                    (GFunc) gmyth_monitor_handler_print,
   565                                    NULL);
   566 
   567                     gchar          *back_msg_action = g_new0(gchar, 1);
   568                     gint            msg_type =
   569                         gmyth_monitor_handler_is_backend_message(monitor,
   570                                                                  strlist,
   571                                                                  &back_msg_action);
   572 
   573                     if (monitor != NULL
   574                         && msg_type != GMYTH_BACKEND_NO_MESSAGE)
   575                         g_signal_emit(monitor, GMYTH_MONITOR_HANDLER_GET_CLASS(monitor)->backend_events_handler_signal_id, 0,   /* details 
   576                                                                                                                                  */
   577                                       msg_type, back_msg_action);
   578 
   579                     if (back_msg_action != NULL)
   580                         g_free(back_msg_action);
   581 
   582                 }
   583 
   584             }
   585 
   586             if (strlist != NULL) {
   587                 g_object_unref(strlist);
   588                 strlist = NULL;
   589             }
   590 
   591             io_cond = g_io_channel_get_buffer_condition(io_channel);
   592 
   593             g_usleep(500);
   594 
   595         }
   596         while (recv <= 0 && ((io_cond & G_IO_HUP) == 0));
   597 
   598         gmyth_debug("\tMONITOR EVENT: Read %d bytes\n", recv);
   599 
   600     }                           /* main GThread while */
   601 
   602   clean_up:
   603     myth_control_release_context(monitor);
   604 
   605     g_thread_exit(ret);
   606 
   607     return (gpointer) ret;
   608 
   609 }
   610 
   611 /** 
   612  * Opens connection events' socket the the Monitor socket on 
   613  * MythTV backend server.
   614  * 
   615  * @param monitor The GMythMonitorHandler instance.
   616  * 
   617  * @return <code>true</code>, if the socket was successfully opened.
   618  */
   619 static          gboolean
   620 gmyth_connect_to_backend_monitor(GMythMonitorHandler * monitor)
   621 {
   622     gboolean        ret = TRUE;
   623 
   624     monitor->event_sock = gmyth_socket_new();
   625 
   626     /*
   627      * Connects the socket, send Mythtv ANN Monitor and verify Mythtv
   628      * protocol version 
   629      */
   630     if (!gmyth_socket_connect_to_backend_events(monitor->event_sock,
   631                                                 monitor->hostname,
   632                                                 monitor->port, FALSE)) {
   633         g_object_unref(monitor->event_sock);
   634         monitor->event_sock = NULL;
   635         ret = FALSE;
   636     }
   637 
   638     return ret;
   639 }
   640 
   641 /** 
   642  * Opens connection the the Monitor socket on MythTV backend server,
   643  * where all status messages are notified to the client.
   644  * 
   645  * @param monitor The GMythMonitorHandler instance.
   646  * @param channel The GIOChannel instance to the Monitor socket.
   647  * 
   648  * @return Pointer to the boolean value, and it is <code>true</code> only if the 
   649  * 				 GMythMonitorHandler could be configured.
   650  */
   651 static          gboolean
   652 gmyth_monitor_handler_setup(GMythMonitorHandler * monitor,
   653                             GIOChannel * channel)
   654 {
   655     gboolean        ret = TRUE;
   656 
   657     if (channel != NULL) {
   658         monitor->allow_msgs_listener = TRUE;
   659 
   660         monitor->th =
   661             g_thread_create((GThreadFunc) gmyth_monitor_handler_listener,
   662                             monitor, TRUE, NULL);
   663         gmyth_debug("MONITOR GThread created!");
   664     } else {
   665         ret = FALSE;
   666         goto cleanup;
   667     }
   668 
   669     if (NULL == monitor->th) {
   670         gmyth_debug
   671             ("[%s] Error adding GThread listener function to the IO control channel!\n",
   672              __FUNCTION__);
   673         ret = FALSE;
   674         goto cleanup;
   675     }
   676 
   677   cleanup:
   678 
   679     return ret;
   680 }
   681 
   682 /** 
   683  * Starts the MonitorHandler thread to the GIOWatcher.
   684  * 
   685  * @param monitor The GMythMonitorHandler instance.
   686  * 
   687  * @return <code>true</code>, if the MonitorHandler was started.
   688  */
   689 gboolean
   690 gmyth_monitor_handler_start(GMythMonitorHandler * monitor)
   691 {
   692     gboolean        ret = TRUE;
   693 
   694     if (!(ret = g_thread_supported())) {
   695         gmyth_debug("Thread system wasn't initialized, starting NOW!!!");
   696         g_thread_init(NULL);
   697     }
   698 
   699     ret =
   700         gmyth_monitor_handler_setup(monitor,
   701                                     monitor->event_sock->sd_io_ch);
   702     if (ret) {
   703         gmyth_debug
   704             ("\n[%s]\tOK! Starting listener on the MONITOR event socket...[thread location = %p]\n",
   705              __FUNCTION__, g_thread_self());
   706     } else {
   707         gmyth_debug
   708             ("\n[%s]\tERROR! Coudn't start listener on the MONITOR event socket...[thread location = %p]\n",
   709              __FUNCTION__, g_thread_self());
   710         ret = FALSE;
   711     }
   712 
   713     gmyth_debug
   714         ("[%s] Watch listener function over the IO control channel? %s!!!\n",
   715          __FUNCTION__, (ret == TRUE ? "YES" : "NO"));
   716 
   717     return ret;
   718 }