]> rtime.felk.cvut.cz Git - frescor/forb.git/blobdiff - src/port.c
Fixed problem with port destroying
[frescor/forb.git] / src / port.c
index c6d5b2f502eb2bb3c3c353eb8ffd41134ab13dd8..fd79aa8f9085aaf29befb56b9b757919c53649b5 100644 (file)
 #include "proto.h"
 #include <forb/config.h>
 #include "iop.h"
+#include <ul_log.h>
+
+extern UL_LOG_CUST(ulogd_forb_port);
+
 /** 
  * Registers a new port in FORB and run receiver thread on it to
  * receive FORB messages through this prot. 
@@ -90,7 +94,13 @@ int forb_register_port(forb_t *forb, forb_port_t *port)
        return 0;
 err3:
        port->finish = true;
-       /* TODO: Wait for the thread to finish - we need some FOSA API for this */
+       /* FIXME: This is Aquosa specific - cancelation should be
+        * added to FOSA. */
+       pthread_cancel(port->receiver_thread.pthread_id);
+       pthread_cancel(port->discovery_thread.pthread_id);
+
+       pthread_join(port->receiver_thread.pthread_id, NULL);
+       pthread_join(port->discovery_thread.pthread_id, NULL);
 err2:
        CDR_codec_release_buffer(&port->codec);
 err:
@@ -104,15 +114,25 @@ err:
 void forb_destroy_port(forb_port_t *port)
 {
        forb_t *forb = port->forb;
-       
+       void *thread_return;
+
        port->finish = true;    /* Exit all the threads */
+       
+       /* FIXME: There is no FOSA API for thread cancelation. */
+       pthread_cancel(port->receiver_thread.pthread_id);
 
-/*     fosa_mutex_lock(&forb->port_mutex); */
-/*     forb_port_delete(forb, port); */
-/*     fosa_mutex_unlock(&forb->port_mutex); */
+       /* 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);
 
-       /* TODO: Wait for the thread to finish - we need some FOSA API for this */
-       //fosa_cond_wait(port->threads)
+       /* 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);
+       pthread_join(port->discovery_thread.pthread_id, &thread_return);
 
        if (port->proto->port_destroy) {
                port->proto->port_destroy(port);
@@ -120,6 +140,12 @@ void forb_destroy_port(forb_port_t *port)
 
        forb_peer_delete_by_port(forb, port);
 
+       CDR_codec_release_buffer(&port->codec);
+
+       fosa_mutex_lock(&forb->port_mutex);
+       forb_port_delete(forb, port);
+       fosa_mutex_unlock(&forb->port_mutex);
+
        /* TODO: reference counting */
        forb_free(port);
 }