Provided by: libglobus-net-manager-doc_0.14-2_all bug

NAME

       globus_net_manager_tutorial - Net Manager Implementation Tutorial This example uses
       functionality from globus_common and globus_net_manager modules, so the headers for those
       must be included:

       #include "globus_common.h"
       #include "globus_net_manager.h"

        To implement a network manager, define a struct globus_net_manager_s containing pointers
       to the functions in your code that you want invoked during network events, and pass that
       to globus_net_manager_register(). Applications which use the Context functions or the
       Globus XIO Net Manager Driver will invoke your functions as network operations occur. For
       this example (and I would imagine most real implementations), the globus_net_manager_t is
       statically initialized, like this:

       static
       globus_net_manager_t                    globus_l_net_manager_logging = {
           "logging",
           globus_l_net_manager_logging_pre_listen,
           globus_l_net_manager_logging_post_listen,
           globus_l_net_manager_logging_end_listen,
           globus_l_net_manager_logging_pre_accept,
           globus_l_net_manager_logging_post_accept,
           globus_l_net_manager_logging_pre_connect,
           globus_l_net_manager_logging_post_connect,
           globus_l_net_manager_logging_pre_close,
           globus_l_net_manager_logging_post_close
       };

        For the examples provided in this library, the globus_net_manager_s is registered during
       module activation in a globus_extension module. This method makes it easy to use network
       managers in a shared library environment. This is also a good place to initialize any
       state that you need to retain between calls to the network manager.

       To implement this, do the following:

       static
       int
       globus_l_net_manager_logging_activate(void)
       {
           globus_hashtable_init(
               &globus_l_nm_logging_logfiles,
               7,
               globus_hashtable_string_hash,
               globus_hashtable_string_keyeq);
           int rc = globus_module_activate(GLOBUS_NET_MANAGER_MODULE);
           if (rc == 0)
           {
               rc = globus_net_manager_register(
                   &globus_l_net_manager_logging,
                   GlobusExtensionMyModule(globus_net_manager_logging));
           }
           return rc;
       }

       static
       void
       globus_l_logging_logfiles_destroy(void *datum)
       {
           globus_l_nm_logging_logref_t        *logref = datum;
           if (logref)
           {
               free(logref->key);
               fclose(logref->handle);
               free(logref);
           }
       }

       static
       int
       globus_l_net_manager_logging_deactivate(void)
       {
           globus_hashtable_destroy_all(
                   &globus_l_nm_logging_logfiles,
                   globus_l_logging_logfiles_destroy);

           int rc = globus_net_manager_unregister(&globus_l_net_manager_logging);
           if (rc == 0)
           {
               rc = globus_module_deactivate(GLOBUS_NET_MANAGER_MODULE);
           }
           return rc;
       }

       Finally, the real work of the manager is done in the functions registered in the
       globus_net_manager_s. For brevity, I'll just include the pre_listen function in this
       tutorial. This function is passed the task-id associated with the operation, the transport
       ('tcp', 'udp', 'udt', etc) used by the network, and whatever attributes are associated
       with the operation. If we wanted to modify things before they were processed by the
       network, we could create a modified copy of the attributes in the pre_listen function and
       return them via the attr_array_out parameter. In this case, we simply print out the
       information we've received from the network stack.

       static
       globus_result_t
       globus_l_net_manager_logging_pre_listen(
           struct globus_net_manager_s        *manager,
           const globus_net_manager_attr_t    *manager_attr_array,
           const char                         *task_id,
           const char                         *transport,
           const globus_net_manager_attr_t    *attr_array,
           globus_net_manager_attr_t         **attr_array_out)
       {
           FILE *                              logfile;
           logfile = globus_l_net_manager_logging_get_logfile(manager_attr_array);
           globus_l_net_manager_logging_log_header(logfile, manager, task_id, transport, "pre_listen");
           globus_l_net_manager_logging_log_attrs(logfile, attr_array);
           globus_l_net_manager_logging_log_footer(logfile);
           return GLOBUS_SUCCESS;
       }
       /* globus_l_net_manager_logging_pre_listen() */