]> rtime.felk.cvut.cz Git - frescor/forb.git/blobdiff - src/port.c
forb: Split forb_port_destroy() to stop and destroy phases
[frescor/forb.git] / src / port.c
index de4e2eeb2d3140304c24ec66a33de8d7e84ee431..029f593faecf1e128d169fa8d8c177c1c59889c0 100644 (file)
 /* covered by the GNU Public License.                                    */
 /**************************************************************************/
 
+/**
+ * @file   port.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Sun Oct 12 17:36:13 2008
+ * 
+ * @brief  Implementation of port manipulation functions.
+ * 
+ * 
+ */
+
+
 #include "port.h"
 #include "proto.h"
+#include "object.h"
 #include <forb/config.h>
 #include "iop.h"
 #include <ul_log.h>
+#include "discovery.h"
 
 extern UL_LOG_CUST(ulogd_forb_port);
 
@@ -58,15 +71,17 @@ extern UL_LOG_CUST(ulogd_forb_port);
  * 
  * @param forb Where to register the new port.
  * 
- * @param port Port to register. The memory for @a port should be
- * forb_malloced, since forb_free() is called on the port on destroy
- * operation.
+ * @param port Port to register. The @c desc field should be
+ * initialized prior calling this function. The memory for @a port
+ * should be forb_malloced, since forb_free() is called on the port on
+ * destroy operation.
  *
  * @return Zero on success, FOSA error code on error.
  */
-int forb_register_port(forb_t *forb, forb_port_t *port)
+int forb_register_port(forb_orb orb, forb_port_t *port)
 {
        int ret;
+       forb_t *forb = forb_data(orb);
        
        port->forb = forb;
        port->finish = false;
@@ -80,20 +95,30 @@ int forb_register_port(forb_t *forb, forb_port_t *port)
        forb_syncobj_init(&port->hello, 0);
        forb_syncobj_init(&port->reply_processed, 0);
 
-       CDR_codec_init_static(&port->codec);
-       if (!CDR_buffer_init(&port->codec, CONFIG_FORB_RECV_BUF_SIZE, 0)) {
+       FORB_CDR_codec_init_static(&port->codec, forb->orb);
+       if (!FORB_CDR_buffer_init(&port->codec, CONFIG_FORB_RECV_BUF_SIZE, 0)) {
                ret = FOSA_ENOMEM;
                goto err;
        }
+
+       if (port->desc.proto->register_cb) {
+               port->desc.proto->register_cb(port);
+       }
+       
        ret = fosa_thread_create(&port->receiver_thread, NULL,
                                 forb_iop_receiver_thread, port);
        if (ret != 0)
                goto err2;
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT
+       /* For reliability reasons, we do not use discovery protocol
+        * when INET is the default communication protocol. */
        ret = fosa_thread_create(&port->discovery_thread, NULL,
                                 forb_iop_discovery_thread, port);
        if (ret != 0)
                goto err3;
+#endif
        return 0;
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT
 err3:
        port->finish = true;
        /* FIXME: This is Aquosa specific - cancelation should be
@@ -103,8 +128,9 @@ err3:
 
        pthread_join(port->receiver_thread.pthread_id, NULL);
        pthread_join(port->discovery_thread.pthread_id, NULL);
+#endif
 err2:
-       CDR_codec_release_buffer(&port->codec);
+       FORB_CDR_codec_release_buffer(&port->codec);
 err:
        fosa_mutex_lock(&forb->port_mutex);
        forb_port_delete(forb, port);
@@ -113,9 +139,13 @@ err:
        return ret;
 }
 
-void forb_destroy_port(forb_port_t *port)
+/** 
+ * Stop receiving requests on the port.
+ * 
+ * @param port 
+ */
+void forb_stop_port(forb_port_t *port)
 {
-       forb_t *forb = port->forb;
        void *thread_return;
 
        port->finish = true;    /* Exit all the threads */
@@ -126,25 +156,46 @@ void forb_destroy_port(forb_port_t *port)
        /* FIXME: Canceling discovery thread sometimes didn't
         * work. The discovery thread stayed forever in the
         * pthread_cond_timedwait(). */
-       //pthread_cancel(port->discovery_thread.pthread_id);
-
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT
+       pthread_cancel(port->discovery_thread.pthread_id);
+#endif
        /* Sometimes, cancelation doesn't work and the
         * discovery_thread hangs in pthread_cond_timedwait
         * infinitely. */
        forb_syncobj_signal(&port->hello);
        
        pthread_join(port->receiver_thread.pthread_id, &thread_return);
+#ifndef CONFIG_FORB_PROTO_INET_DEFAULT
        pthread_join(port->discovery_thread.pthread_id, &thread_return);
+#endif
+}
 
-       if (port->proto->port_destroy) {
-               port->proto->port_destroy(port);
-       }
 
+/** 
+ * Destroys the port and all resources associated with it.
+ * 
+ * @param port 
+ */
+void forb_destroy_port(forb_port_t *port)
+{
+       forb_t *forb = port->forb;
+       
        /* Because of no locking of port->peers, this must be called
         * after receiver thread is stopped. */
-       forb_peer_delete_by_port(forb, port);
+       forb_peer_t *peer;
+       ul_list_for_each_cut(forb_port_peer, port, peer) {
+               forb_peer_get(peer);
+               forb_peer_disconnected(peer);
+               forb_peer_put(peer);
+       }
+       if (port->new_peer)
+               forb_peer_put(port->new_peer);
+
+       if (port->desc.proto->port_destroy) {
+               port->desc.proto->port_destroy(port);
+       }
 
-       CDR_codec_release_buffer(&port->codec);
+       FORB_CDR_codec_release_buffer(&port->codec);
 
        fosa_mutex_lock(&forb->port_mutex);
        forb_port_delete(forb, port);