/* 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);
*
* @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;
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
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);
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 */
/* 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);