Resend of GIOP timeout patch

View: New views
6 Messages — Rating Filter:   Alert me  

Resend of GIOP timeout patch

by colding :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi All,

This is just a resend of my timeout patch to prevent it from fading from
our combined attention.


Rationale:
----------
The patch is a revert of my previous timeout approach following well
deserved criticism from Michael. A g_timeout_source based approach is
used instead.


What it does:
-------------
It introduced a new ORB parameter GIOPTimeoutMSEC which is the timeout
value in milliseconds. The default timeout value is 60 seconds unless
modified using this ORB parameter.

A timeout source is added to the link main context for all IPv4 and IPv6
connections unless said connection is a oneway.

The timeout source will be removed when any of the following happens:

1) The timeout triggered (link state = LINK_TIMEOUT)
2) A respons was received on the connection
3) The connection was destroyed

A CORBA timeout exception (ex_CORBA_TIMEOUT) is thrown if the timeout
triggered.


Please:
-------
Please review the patch so that we can get the current broken timeout
behavior replaced with something that actually has a fighting chance of
working properly. I would really like to commit sooner rather than later
considering how bad the old timeout approach turned out to be.


Thanks,
  jules



Index: src/orb/orb-core/corba-orb.c
===================================================================
--- src/orb/orb-core/corba-orb.c (revision 2003)
+++ src/orb/orb-core/corba-orb.c (working copy)
@@ -61,7 +61,7 @@
 static char        *orbit_naming_ref         = NULL;
 static GSList      *orbit_initref_list       = NULL;
 static gboolean     orbit_use_corbaloc       = FALSE;
-static gint         orbit_timeout_limit      = -1;
+static guint        orbit_timeout_msec       = 60000; /* 60 seconds - 0 will disable timeouts altogether */
 void
 ORBit_ORB_start_servers (CORBA_ORB orb)
 {
@@ -418,7 +418,7 @@
 #endif /* G_ENABLE_DEBUG */
 
  giop_recv_set_limit (orbit_initial_recv_limit);
- giop_recv_set_timeout (orbit_timeout_limit);
+ giop_set_timeout (orbit_timeout_msec);
  giop_init (thread_safe,
    orbit_use_ipv4 || orbit_use_ipv6 ||
    orbit_use_irda || orbit_use_ssl);
@@ -1468,7 +1468,7 @@
  { "ORBDebugFlags",      ORBIT_OPTION_STRING,  &orbit_debug_options },
  { "ORBInitRef",         ORBIT_OPTION_KEY_VALUE,  &orbit_initref_list},
  { "ORBCorbaloc",        ORBIT_OPTION_BOOLEAN, &orbit_use_corbaloc},
- { "GIOPTimeoutLimit",   ORBIT_OPTION_INT,     &orbit_timeout_limit },
+ { "GIOPTimeoutMSEC",    ORBIT_OPTION_ULONG,   &orbit_timeout_msec },
  { NULL,                 0,                    NULL }
 };
 
Index: src/orb/orb-core/corba-object.c
===================================================================
--- src/orb/orb-core/corba-object.c (revision 2003)
+++ src/orb/orb-core/corba-object.c (working copy)
@@ -270,6 +270,7 @@
  retval = TRUE;
  break;
  case LINK_DISCONNECTED:
+ case LINK_TIMEOUT:
  /* Have a go at reviving it */
  dprintf (MESSAGES, "re-connecting dropped cnx %p: ", cnx);
  if (giop_connection_try_reconnect (GIOP_CONNECTION (cnx)) == LINK_CONNECTED)
Index: src/orb/util/orbit-options.c
===================================================================
--- src/orb/util/orbit-options.c (revision 2003)
+++ src/orb/util/orbit-options.c (working copy)
@@ -53,6 +53,9 @@
  case ORBIT_OPTION_INT:
  *(gint *)option->arg = atoi (val);
  break;
+ case ORBIT_OPTION_ULONG:
+ *(guint *)option->arg = strtoul(val, (char **)NULL, 10);
+ break;
  case ORBIT_OPTION_STRING: {
  gchar **str_arg = (char **) option->arg;
 
Index: src/orb/util/orbit-options.h
===================================================================
--- src/orb/util/orbit-options.h (revision 2003)
+++ src/orb/util/orbit-options.h (working copy)
@@ -10,7 +10,8 @@
  ORBIT_OPTION_STRING,
  ORBIT_OPTION_INT,
  ORBIT_OPTION_BOOLEAN,
- ORBIT_OPTION_KEY_VALUE  /* returns GSList of ORBit_option_key_value */
+ ORBIT_OPTION_KEY_VALUE,  /* returns GSList of ORBit_option_key_value */
+ ORBIT_OPTION_ULONG,
 } ORBit_option_type;
 
 typedef struct {
Index: src/orb/GIOP/giop-recv-buffer.c
===================================================================
--- src/orb/GIOP/giop-recv-buffer.c (revision 2003)
+++ src/orb/GIOP/giop-recv-buffer.c (working copy)
@@ -2,6 +2,8 @@
 #include <string.h>
 #include <stdio.h>
 #include <errno.h>
+#include <glib.h>
+#include <glib/gprintf.h>
 
 #include "giop-private.h"
 #include "giop-debug.h"
@@ -686,26 +688,20 @@
 static inline gboolean
 check_got (GIOPMessageQueueEntry *ent)
 {
- return (ent->buffer || !ent->cnx ||
- (ent->cnx->parent.status == LINK_DISCONNECTED));
+ return (ent->buffer ||
+ !ent->cnx ||
+ (ent->cnx->parent.status == LINK_DISCONNECTED) ||
+ (ent->cnx->parent.status == LINK_TIMEOUT));
 }
 
-static glong giop_initial_timeout_limit = GIOP_INITIAL_TIMEOUT_LIMIT;
-
-void
-giop_recv_set_timeout (const glong timeout)
-{
- if (0 < timeout) /* We really do not want (timeout <= 0) as that would potentially block forever */
- giop_initial_timeout_limit = timeout;
-}
-
 GIOPRecvBuffer *
 giop_recv_buffer_get (GIOPMessageQueueEntry *ent,
       gboolean *timeout)
 {
  GIOPThread *tdata = giop_thread_self ();
- GTimeVal tval;
 
+ *timeout = FALSE;
+
  thread_switch:
  if (giop_thread_io ()) {
  ent_lock (ent);
@@ -715,17 +711,8 @@
  ent_unlock (ent);
  giop_thread_queue_process (tdata);
  ent_lock (ent);
- } else {
- if (0 < giop_initial_timeout_limit) {
- g_get_current_time (&tval);
- g_time_val_add (&tval, giop_initial_timeout_limit);
- }
- if (!g_cond_timed_wait (tdata->incoming, tdata->lock, ((0 < giop_initial_timeout_limit) ? &tval : NULL))) {
- *timeout = TRUE;
- break;
- } else
- *timeout = FALSE;
- }
+ } else
+ g_cond_wait (tdata->incoming, tdata->lock);
  }
 
  ent_unlock (ent);
@@ -734,6 +721,7 @@
 
  while (!ent->buffer && ent->cnx &&
        (ent->cnx->parent.status != LINK_DISCONNECTED) &&
+       (ent->cnx->parent.status != LINK_TIMEOUT) &&
        !giop_thread_io())
  link_main_iteration (TRUE);
 
@@ -741,6 +729,17 @@
  goto thread_switch;
  }
 
+ if (ent->cnx->parent.timeout_mutex) {
+ g_mutex_lock (ent->cnx->parent.timeout_mutex);
+ if (ent->cnx->parent.timeout_status == LINK_TIMEOUT_UNKNOWN) {
+ link_io_thread_remove_timeout (ent->cnx->parent.timeout_source_id);
+ ent->cnx->parent.timeout_source_id = 0;
+ ent->cnx->parent.timeout_status = LINK_TIMEOUT_NO;
+ } else
+ *timeout = TRUE;
+ g_mutex_unlock (ent->cnx->parent.timeout_mutex);
+ }
+
  giop_thread_queue_tail_wakeup (tdata);
  giop_recv_list_destroy_queue_entry (ent);
 
@@ -1355,6 +1354,74 @@
  return TRUE;
 }
 
+struct timeout_thread_data {
+ GIOPThread *tdata;
+ LinkConnection *lcnx;
+};
+
+static gboolean
+giop_timeout(gpointer data)
+{
+ gboolean retv = FALSE;
+ LinkConnection *lcnx = ((struct timeout_thread_data*)data)->lcnx;
+ GIOPThread *tdata =  ((struct timeout_thread_data*)data)->tdata;
+
+ g_printf("Timeout function invoked\n");
+
+ g_assert (lcnx->timeout_mutex);
+
+ g_mutex_lock (lcnx->timeout_mutex);
+ if (lcnx->timeout_status == LINK_TIMEOUT_UNKNOWN) {
+ lcnx->timeout_source_id = 0;
+ lcnx->timeout_status = LINK_TIMEOUT_YES;
+ } else {
+ g_mutex_unlock (lcnx->timeout_mutex);
+ retv = TRUE; // do not remove the source - the one who sets timeout_status will do that
+ goto out;
+ }
+ g_mutex_unlock (lcnx->timeout_mutex);
+
+ link_connection_state_changed (lcnx, LINK_TIMEOUT);
+
+ g_mutex_lock (tdata->lock); /* ent_lock */
+ giop_incoming_signal_T (tdata, GIOP_CLOSECONNECTION);
+ g_mutex_unlock (tdata->lock); /* ent_lock */
+
+out:
+ g_object_unref (lcnx);
+ g_free (data);
+
+ return retv;
+}
+
+void
+giop_timeout_add(GIOPConnection *cnx)
+{
+ struct timeout_thread_data *data = NULL;
+ LinkConnection *lcnx = LINK_CONNECTION (cnx);
+ GSource *timeout_source = NULL;
+
+ if (!lcnx->timeout_msec)
+ return;
+
+ g_object_ref (lcnx);
+
+ if (!lcnx->timeout_mutex)
+ lcnx->timeout_mutex = g_mutex_new ();
+
+ g_mutex_lock (lcnx->timeout_mutex);
+ lcnx->timeout_status = LINK_TIMEOUT_UNKNOWN;
+ g_mutex_unlock (lcnx->timeout_mutex);
+
+ data = g_new0 (struct timeout_thread_data, 1);
+ data->tdata = giop_thread_self ();
+ data->lcnx = lcnx;
+
+ g_printf("Adding timeout for %d milliseconds\n", lcnx->timeout_msec);
+
+ lcnx->timeout_source_id = link_io_thread_add_timeout (lcnx->timeout_msec, giop_timeout, data);
+}
+
 GIOPRecvBuffer *
 giop_recv_buffer_use_buf (GIOPConnection *cnx)
 {
@@ -1372,4 +1439,3 @@
 
  return buf;
 }
-
Index: src/orb/GIOP/giop-connection.c
===================================================================
--- src/orb/GIOP/giop-connection.c (revision 2003)
+++ src/orb/GIOP/giop-connection.c (working copy)
@@ -108,6 +108,7 @@
  }
 }
 
+
 static void
 giop_connection_class_init (GIOPConnectionClass *klass)
 {
@@ -192,3 +193,9 @@
  return link_connection_try_reconnect (LINK_CONNECTION (cnx));
 }
 
+void
+giop_set_timeout (guint msec)
+{
+ link_set_timeout (msec);
+}
+
Index: src/orb/GIOP/giop-send-buffer.c
===================================================================
--- src/orb/GIOP/giop-send-buffer.c (revision 2003)
+++ src/orb/GIOP/giop-send-buffer.c (working copy)
@@ -45,6 +45,25 @@
 
 static const GIOP_AddressingDisposition giop_1_2_target_type = GIOP_KeyAddr;
 
+static gboolean
+giop_send_buffer_is_oneway(const GIOPSendBuffer *buf)
+{
+ g_assert (buf);
+
+ switch (buf->giop_version) {
+ case GIOP_1_0:
+ case GIOP_1_1:
+ return (buf->msg.u.request_1_0.response_expected ? FALSE : TRUE);
+ case GIOP_1_2:
+ return (buf->msg.u.request_1_2.response_flags ? FALSE : TRUE);
+ default:
+ break;
+ }
+ g_assert_not_reached();
+
+ return TRUE;
+}
+
 GIOPSendBuffer *
 giop_send_buffer_use_request (GIOPVersion giop_version,
       CORBA_unsigned_long request_id,
@@ -426,6 +445,7 @@
  gboolean        blocking)
 {
  int retval;
+ LinkConnection *lcnx = LINK_CONNECTION (cnx);
  static LinkWriteOpts *non_block = NULL;
 
  if (!non_block)
@@ -434,11 +454,15 @@
  /* FIXME: if a FRAGMENT, assert the 8 byte tail align,
    &&|| giop_send_buffer_align (buf, 8); */
 
- retval = link_connection_writev (
- (LinkConnection *) cnx, buf->iovecs,
- buf->num_used,
- blocking ? NULL : non_block);
+ if (lcnx->timeout_msec && !giop_send_buffer_is_oneway (buf)) {
+ giop_timeout_add (cnx);
+ }
 
+ retval = link_connection_writev (lcnx,
+ buf->iovecs,
+ buf->num_used,
+ blocking ? NULL : non_block);
+
  if (!blocking && retval == LINK_IO_QUEUED_DATA)
  retval = 0;
 
Index: linc2/include/linc/linc-connection.h
===================================================================
--- linc2/include/linc/linc-connection.h (revision 2003)
+++ linc2/include/linc/linc-connection.h (working copy)
@@ -39,7 +39,8 @@
 #define LINK_IS_CONNECTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LINK_TYPE_CONNECTION))
 #define LINK_IS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LINK_TYPE_CONNECTION))
 
-typedef enum { LINK_CONNECTING, LINK_CONNECTED, LINK_DISCONNECTED } LinkConnectionStatus;
+typedef enum { LINK_CONNECTING, LINK_CONNECTED, LINK_DISCONNECTED, LINK_TIMEOUT } LinkConnectionStatus;
+typedef enum { LINK_TIMEOUT_UNKNOWN, LINK_TIMEOUT_YES, LINK_TIMEOUT_NO } LinkTimeoutStatus;
 
 typedef struct _LinkWriteOpts         LinkWriteOpts;
 typedef struct _LinkConnectionPrivate LinkConnectionPrivate;
@@ -61,6 +62,11 @@
  LinkConnectionPrivate  *priv;
 
  GSList                 *idle_broken_callbacks;
+
+ GMutex                 *timeout_mutex;
+ guint                   timeout_msec;
+ guint                   timeout_source_id; // protected by timeout_mutex
+ LinkTimeoutStatus       timeout_status;    // protected by timeout_mutex
 } LinkConnection;
 
 typedef struct {
@@ -153,6 +159,9 @@
 
 void           link_connections_close            (void);
 
+/* set the link timeout in miliseconds */
+extern void link_set_timeout (guint msec);
+
 G_END_DECLS
 
 #endif /* _LINK_CONNECTION_H */
Index: linc2/include/linc/linc.h
===================================================================
--- linc2/include/linc/linc.h (revision 2003)
+++ linc2/include/linc/linc.h (working copy)
@@ -33,12 +33,17 @@
 guint      link_main_idle_add    (GSourceFunc function,
   gpointer    data);
 
-gboolean   link_wait             (void);
+void       link_wait             (void);
 void       link_signal           (void);
 
 gboolean   link_thread_io        (void);
 gboolean   link_thread_safe      (void);
 
+guint      link_io_thread_add_timeout    (guint       interval,
+  GSourceFunc function,
+  gpointer    data);
+void       link_io_thread_remove_timeout (guint source_id);
+
 #ifdef G_OS_WIN32
 void link_map_winsock_error_to_errno (void);
 #endif
Index: linc2/src/linc-debug.h
===================================================================
--- linc2/src/linc-debug.h (revision 2003)
+++ linc2/src/linc-debug.h (working copy)
@@ -25,6 +25,7 @@
 #  define STATE_NAME(s) (((s) == LINK_CONNECTED) ? "Connected" : \
  ((s) == LINK_CONNECTING) ? "Connecting" : \
  ((s) == LINK_DISCONNECTED) ? "Disconnected" : \
+ ((s) == LINK_TIMEOUT) ? "Timeout" : \
  "Invalid state")
 #  ifdef CONNECTION_DEBUG_FLAG
 extern gboolean link_connection_debug_flag;
Index: linc2/src/linc-connection.c
===================================================================
--- linc2/src/linc-connection.c (revision 2003)
+++ linc2/src/linc-connection.c (working copy)
@@ -27,6 +27,7 @@
 #include <linc/linc-connection.h>
 
 static GObjectClass *parent_class = NULL;
+static guint _link_timeout = 0;
 
 enum {
  BROKEN,
@@ -288,6 +289,7 @@
  break;
 
  case LINK_DISCONNECTED:
+ case LINK_TIMEOUT:
  link_source_remove (cnx);
  link_close_fd (cnx);
  queue_free (cnx);
@@ -440,6 +442,16 @@
  g_free (cnx->remote_serv_info);
  cnx->remote_serv_info = remote_serv_info;
 
+ switch (cnx->proto->family) {
+ case AF_INET:
+ case AF_INET6:
+ if (_link_timeout && !cnx->timeout_msec) /* this should'nt happen twice but I'm always paranoid... */
+ cnx->timeout_msec = _link_timeout;
+ break;
+ default:
+ break;
+ }
+
  d_printf ("Cnx from fd (%d) '%s', '%s', '%s'\n",
  fd, proto->name,
  remote_host_info ? remote_host_info : "<Null>",
@@ -635,10 +647,8 @@
 static LinkConnectionStatus
 link_connection_wait_connected_T (LinkConnection *cnx)
 {
- while (cnx && cnx->status == LINK_CONNECTING) {
- if (!link_wait ())
- link_connection_disconnect (cnx);
- }
+ while (cnx && cnx->status == LINK_CONNECTING)
+ link_wait ();
 
  return cnx ? cnx->status : LINK_DISCONNECTED;
 }
@@ -661,12 +671,8 @@
  cnx->inhibit_reconnect = FALSE;
  dispatch_callbacks_drop_lock (cnx);
  g_main_context_release (NULL);
- } else {
- if (!link_wait ()) {
- link_connection_disconnect (cnx);
- break;
- }
- }
+ } else
+ link_wait ();
  }
 
  if (cnx->status != LINK_DISCONNECTED)
@@ -1254,6 +1260,13 @@
 
  g_free (cnx->priv);
 
+ if (cnx->timeout_mutex)
+ g_mutex_free (cnx->timeout_mutex);
+
+ if (cnx->timeout_source_id)
+ link_io_thread_remove_timeout (cnx->timeout_source_id);
+
+
 #ifdef G_ENABLE_DEBUG
  g_assert (g_list_find(cnx_list, cnx) == NULL);
 #endif
@@ -1269,6 +1282,12 @@
  cnx->priv = g_new0 (LinkConnectionPrivate, 1);
  cnx->priv->fd = -1;
  cnx->priv->was_disconnected = FALSE;
+
+ cnx->timeout_mutex = NULL;
+ cnx->timeout_msec = 0;
+ cnx->timeout_source_id = 0;
+ cnx->timeout_status = LINK_TIMEOUT_UNKNOWN;
+
 #ifdef CONNECTION_DEBUG
  cnx->priv->total_read_bytes = 0;
  cnx->priv->total_written_bytes = 0;
@@ -1568,3 +1587,10 @@
 
  g_list_free (cnx);
 }
+
+void
+link_set_timeout (guint msec)
+{
+ _link_timeout = msec;
+}
+
Index: linc2/src/linc.c
===================================================================
--- linc2/src/linc.c (revision 2003)
+++ linc2/src/linc.c (working copy)
@@ -52,9 +52,6 @@
 SSL_CTX    *link_ssl_ctx;
 #endif
 
-/* max time to wait for the link condition to get signaled - 10 seconds */
-#define LINK_WAIT_TIMEOUT_USEC (10000000)
-
 static void link_dispatch_command (gpointer data, gboolean immediate);
 
 gboolean
@@ -537,28 +534,17 @@
  }
 }
 
-gboolean
+void
 link_wait (void)
 {
- GTimeVal gtime;
-
  if (!(link_is_thread_safe && link_is_io_in_thread)) {
  link_unlock ();
  link_main_iteration (TRUE);
  link_lock ();
  } else {
  g_assert (link_main_cond != NULL);
-
- g_get_current_time (>ime);
- g_time_val_add (>ime, LINK_WAIT_TIMEOUT_USEC);
- if (!g_cond_timed_wait (link_main_cond, link_main_lock, >ime)) {
- if (link_is_locked ())
- link_unlock ();
- return FALSE;
- }
+ g_cond_wait (link_main_cond, link_main_lock);
  }
-
- return TRUE;
 }
 
 
@@ -568,3 +554,34 @@
 {
  return link_mutex_is_locked (link_main_lock);
 }
+
+/* Hack */
+guint
+link_io_thread_add_timeout (guint       interval,
+                            GSourceFunc function,
+                            gpointer    data)
+{
+ guint id;
+ GSource *tsrc;
+
+ tsrc = g_timeout_source_new (interval);
+ g_source_set_priority (tsrc, G_PRIORITY_HIGH_IDLE);
+ g_source_set_callback (tsrc, function, data, NULL);
+ g_source_set_can_recurse (tsrc, TRUE);
+ id = g_source_attach (tsrc, link_thread_context);
+ g_source_unref (tsrc);
+
+ return id;
+}
+
+void
+link_io_thread_remove_timeout (guint source_id)
+{
+ GSource *tsrc;
+
+ if (!source_id)
+ return;
+
+ tsrc = g_main_context_find_source_by_id (link_thread_context, source_id);
+ g_source_destroy (tsrc);
+}
Index: linc2/ChangeLog
===================================================================
--- linc2/ChangeLog (revision 2003)
+++ linc2/ChangeLog (working copy)
@@ -1,3 +1,24 @@
+2007-06-19  Jules Colding  <colding@...>
+
+ * src/linc-connection.c (link_connection_init): Initialize
+ timeout members in the LinkConnection structure.
+ (link_set_timeout): New function to set the timeout value.
+
+2007-06-18  Jules Colding  <colding@...>
+
+ * src/linc-connection.c (link_connection_from_fd_T): Initiate
+ timeout members of the link connection iff:
+ 1) The connection is IPv4 or IPv6
+ 2) It is not a oneway
+ 3) The timeout parameter is non-zero
+
+ * include/linc/linc-connection.h (struct):
+ 1) timeout mutex
+ 2) timeout value in milliseconds
+ 3) timeout status
+
+ Furthermore declare link_set_timeout()
+
 ========================== ORBit2-2.14.8 ========================
 
 2007-02-27  Kjartan Maraas  <kmaraas@...>
Index: include/orbit/GIOP/giop-connection.h
===================================================================
--- include/orbit/GIOP/giop-connection.h (revision 2003)
+++ include/orbit/GIOP/giop-connection.h (working copy)
@@ -53,6 +53,9 @@
 #define         giop_connection_ref(cnx)      link_connection_ref(cnx)
 #define         giop_connection_unref(cnx)    link_connection_unref(cnx)
 
+/* set the link timeout in milliseconds */
+extern void giop_set_timeout (guint msec);
+
 #endif /* ORBIT2_INTERNAL_API */
 
 G_END_DECLS
Index: include/orbit/GIOP/giop.h
===================================================================
--- include/orbit/GIOP/giop.h (revision 2003)
+++ include/orbit/GIOP/giop.h (working copy)
@@ -23,7 +23,6 @@
 gboolean    giop_thread_io         (void);
 GIOPThread *giop_thread_self       (void);
 void        giop_invoke_async      (GIOPMessageQueueEntry *ent);
-void        giop_recv_set_timeout  (const glong timeout);
 void        giop_recv_set_limit    (glong limit);
 glong       giop_recv_get_limit    (void);
 void        giop_incoming_signal_T (GIOPThread *tdata, GIOPMsgType t);
@@ -47,7 +46,6 @@
 gboolean    giop_thread_queue_empty_T    (GIOPThread *tdata);
 void        giop_thread_queue_tail_wakeup(GIOPThread *tdata);
 
-
 #endif /* ORBIT2_INTERNAL_API */
 
 G_END_DECLS
Index: include/orbit/GIOP/giop-types.h
===================================================================
--- include/orbit/GIOP/giop-types.h (revision 2003)
+++ include/orbit/GIOP/giop-types.h (working copy)
@@ -35,10 +35,8 @@
  gpointer dummy);
 };
 
-#define GIOP_INITIAL_TIMEOUT_LIMIT (30000000) /* 30 seconds */
+#define GIOP_INITIAL_MSG_SIZE_LIMIT (256*1024)
 
-#define GIOP_INITIAL_MSG_SIZE_LIMIT (256*1024) /* in bytes */
-
 typedef enum {
  GIOP_CONNECTION_SSL
 } GIOPConnectionOptions;
Index: include/orbit/GIOP/giop-recv-buffer.h
===================================================================
--- include/orbit/GIOP/giop-recv-buffer.h (revision 2003)
+++ include/orbit/GIOP/giop-recv-buffer.h (working copy)
@@ -74,7 +74,9 @@
 void                        giop_recv_list_zap              (GIOPConnection *cnx);
 gboolean                    giop_connection_handle_input    (LinkConnection *lcnx);
 void                        giop_connection_destroy_frags   (GIOPConnection *cnx);
+extern void                 giop_timeout_add                (GIOPConnection *cnx);
 
+
 #endif /* ORBIT2_INTERNAL_API */
 
 G_END_DECLS



_______________________________________________
orbit-list mailing list
orbit-list@...
http://mail.gnome.org/mailman/listinfo/orbit-list

Re: Resend of GIOP timeout patch

by michael meeks :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Jules,

On Wed, 2007-07-04 at 10:33 +0200, Jules Colding wrote:
> This is just a resend of my timeout patch to prevent it from fading from
> our combined attention.

        Sure; looks a lot better than what was there. Perhaps bin the g_printf
- but ultimately, the best review / inclusion criterion is now working
test cases run as part of 'make check' :-)

        HTH,

                Michael.

--
 michael.meeks@...  <><, Pseudo Engineer, itinerant idiot


_______________________________________________
orbit-list mailing list
orbit-list@...
http://mail.gnome.org/mailman/listinfo/orbit-list

Re: Resend of GIOP timeout patch

by colding :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, 2007-07-04 at 09:42 +0000, Michael Meeks wrote:
> Hi Jules,
>
> On Wed, 2007-07-04 at 10:33 +0200, Jules Colding wrote:
> > This is just a resend of my timeout patch to prevent it from fading from
> > our combined attention.
>
> Sure; looks a lot better than what was there. Perhaps bin the g_printf

Leftover from debugging. Will remove.

> - but ultimately, the best review / inclusion criterion is now working
> test cases run as part of 'make check' :-)

OK, I'll put a modified echo test case into make check. Stay tuned.

> HTH,

It does :-)

Best regards,
  jules


_______________________________________________
orbit-list mailing list
orbit-list@...
http://mail.gnome.org/mailman/listinfo/orbit-list

Re: Resend of GIOP timeout patch

by colding :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, 2007-07-04 at 12:00 +0200, Jules Colding wrote:

> On Wed, 2007-07-04 at 09:42 +0000, Michael Meeks wrote:
> > Hi Jules,
> >
> > On Wed, 2007-07-04 at 10:33 +0200, Jules Colding wrote:
> > > This is just a resend of my timeout patch to prevent it from fading from
> > > our combined attention.
> >
> > Sure; looks a lot better than what was there. Perhaps bin the g_printf
>
> Leftover from debugging. Will remove.
>
> > - but ultimately, the best review / inclusion criterion is now working
> > test cases run as part of 'make check' :-)
>
> OK, I'll put a modified echo test case into make check. Stay tuned.
The attached patch works perfectly on Gentoo dual AMD64. Should I
commit?

Best regards,
  jules


>
> _______________________________________________
> orbit-list mailing list
> orbit-list@...
> http://mail.gnome.org/mailman/listinfo/orbit-list

[timeout.patch]


Property changes on: .
___________________________________________________________________
Name: svn:ignore
   - config.guess
config.sub
config.log
config.status
ltconfig
ltmain.sh
aclocal.m4
stamp-h.in
stamp-h
config.h
INSTALL
missing
mkinstalldirs
install-sh
Makefile
Makefile.in
configure
config.h.in
obj
ORBit.spec
ORBit-2.0.pc
ORBit-CosNaming-2.0.pc
orbit2-config
orbit-config
libtool
config.cache
ORBit-2.0.pc
ORBit-CosNaming-2.0.pc
ORBit2-*.tar.gz
ORBit-*.tar.gz
autom4te.cache
ORBit-imodule-2.0.pc
stamp-h1
autom4te*
depcomp
gtk-doc.make
orbit2-zip

   + config.guess
config.sub
config.log
config.status
ltconfig
ltmain.sh
aclocal.m4
stamp-h.in
stamp-h
config.h
INSTALL
missing
mkinstalldirs
install-sh
Makefile
Makefile.in
configure
config.h.in
obj
ORBit.spec
ORBit-2.0.pc
ORBit-CosNaming-2.0.pc
orbit2-config
orbit-config
libtool
config.cache
ORBit-2.0.pc
ORBit-CosNaming-2.0.pc
ORBit2-*.tar.gz
ORBit-*.tar.gz
autom4te.cache
ORBit-imodule-2.0.pc
stamp-h1
autom4te*
depcomp
gtk-doc.make
orbit2-zip
configure.in.orig
ORBit-2.0-uninstalled.pc
semantic.cache
ChangeLog.orig
ORBit-imodule-2.0-uninstalled.pc
cscope.out
ORBit-CosNaming-2.0-uninstalled.pc
cscope.files



Index: src/orb/orb-core/corba-orb.c
===================================================================
--- src/orb/orb-core/corba-orb.c (revision 2004)
+++ src/orb/orb-core/corba-orb.c (working copy)
@@ -61,7 +61,7 @@
 static char        *orbit_naming_ref         = NULL;
 static GSList      *orbit_initref_list       = NULL;
 static gboolean     orbit_use_corbaloc       = FALSE;
-static gint         orbit_timeout_limit      = -1;
+static guint        orbit_timeout_msec       = 60000; /* 60 seconds - 0 will disable timeouts altogether */
 void
 ORBit_ORB_start_servers (CORBA_ORB orb)
 {
@@ -418,7 +418,7 @@
 #endif /* G_ENABLE_DEBUG */
 
  giop_recv_set_limit (orbit_initial_recv_limit);
- giop_recv_set_timeout (orbit_timeout_limit);
+ giop_set_timeout (orbit_timeout_msec);
  giop_init (thread_safe,
    orbit_use_ipv4 || orbit_use_ipv6 ||
    orbit_use_irda || orbit_use_ssl);
@@ -1468,7 +1468,7 @@
  { "ORBDebugFlags",      ORBIT_OPTION_STRING,  &orbit_debug_options },
  { "ORBInitRef",         ORBIT_OPTION_KEY_VALUE,  &orbit_initref_list},
  { "ORBCorbaloc",        ORBIT_OPTION_BOOLEAN, &orbit_use_corbaloc},
- { "GIOPTimeoutLimit",   ORBIT_OPTION_INT,     &orbit_timeout_limit },
+ { "GIOPTimeoutMSEC",    ORBIT_OPTION_ULONG,   &orbit_timeout_msec },
  { NULL,                 0,                    NULL }
 };
 
Index: src/orb/orb-core/corba-object.c
===================================================================
--- src/orb/orb-core/corba-object.c (revision 2004)
+++ src/orb/orb-core/corba-object.c (working copy)
@@ -270,6 +270,7 @@
  retval = TRUE;
  break;
  case LINK_DISCONNECTED:
+ case LINK_TIMEOUT:
  /* Have a go at reviving it */
  dprintf (MESSAGES, "re-connecting dropped cnx %p: ", cnx);
  if (giop_connection_try_reconnect (GIOP_CONNECTION (cnx)) == LINK_CONNECTED)
Index: src/orb/util/orbit-options.c
===================================================================
--- src/orb/util/orbit-options.c (revision 2004)
+++ src/orb/util/orbit-options.c (working copy)
@@ -53,6 +53,9 @@
  case ORBIT_OPTION_INT:
  *(gint *)option->arg = atoi (val);
  break;
+ case ORBIT_OPTION_ULONG:
+ *(guint *)option->arg = strtoul(val, (char **)NULL, 10);
+ break;
  case ORBIT_OPTION_STRING: {
  gchar **str_arg = (char **) option->arg;
 
Index: src/orb/util/orbit-options.h
===================================================================
--- src/orb/util/orbit-options.h (revision 2004)
+++ src/orb/util/orbit-options.h (working copy)
@@ -10,7 +10,8 @@
  ORBIT_OPTION_STRING,
  ORBIT_OPTION_INT,
  ORBIT_OPTION_BOOLEAN,
- ORBIT_OPTION_KEY_VALUE  /* returns GSList of ORBit_option_key_value */
+ ORBIT_OPTION_KEY_VALUE,  /* returns GSList of ORBit_option_key_value */
+ ORBIT_OPTION_ULONG,
 } ORBit_option_type;
 
 typedef struct {
Index: src/orb/GIOP/giop-recv-buffer.c
===================================================================
--- src/orb/GIOP/giop-recv-buffer.c (revision 2004)
+++ src/orb/GIOP/giop-recv-buffer.c (working copy)
@@ -2,6 +2,8 @@
 #include <string.h>
 #include <stdio.h>
 #include <errno.h>
+#include <glib.h>
+#include <glib/gprintf.h>
 
 #include "giop-private.h"
 #include "giop-debug.h"
@@ -686,26 +688,21 @@
 static inline gboolean
 check_got (GIOPMessageQueueEntry *ent)
 {
- return (ent->buffer || !ent->cnx ||
- (ent->cnx->parent.status == LINK_DISCONNECTED));
+ return (ent->buffer ||
+ !ent->cnx ||
+ (ent->cnx->parent.status == LINK_DISCONNECTED) ||
+ (ent->cnx->parent.status == LINK_TIMEOUT));
 }
 
-static glong giop_initial_timeout_limit = GIOP_INITIAL_TIMEOUT_LIMIT;
-
-void
-giop_recv_set_timeout (const glong timeout)
-{
- if (0 < timeout) /* We really do not want (timeout <= 0) as that would potentially block forever */
- giop_initial_timeout_limit = timeout;
-}
-
 GIOPRecvBuffer *
 giop_recv_buffer_get (GIOPMessageQueueEntry *ent,
       gboolean *timeout)
 {
- GIOPThread *tdata = giop_thread_self ();
- GTimeVal tval;
+ GIOPThread *tdata = NULL;
 
+ *timeout = FALSE;
+ tdata = giop_thread_self ();
+
  thread_switch:
  if (giop_thread_io ()) {
  ent_lock (ent);
@@ -715,17 +712,8 @@
  ent_unlock (ent);
  giop_thread_queue_process (tdata);
  ent_lock (ent);
- } else {
- if (0 < giop_initial_timeout_limit) {
- g_get_current_time (&tval);
- g_time_val_add (&tval, giop_initial_timeout_limit);
- }
- if (!g_cond_timed_wait (tdata->incoming, tdata->lock, ((0 < giop_initial_timeout_limit) ? &tval : NULL))) {
- *timeout = TRUE;
- break;
- } else
- *timeout = FALSE;
- }
+ } else
+ g_cond_wait (tdata->incoming, tdata->lock);
  }
 
  ent_unlock (ent);
@@ -734,6 +722,7 @@
 
  while (!ent->buffer && ent->cnx &&
        (ent->cnx->parent.status != LINK_DISCONNECTED) &&
+       (ent->cnx->parent.status != LINK_TIMEOUT) &&
        !giop_thread_io())
  link_main_iteration (TRUE);
 
@@ -741,6 +730,17 @@
  goto thread_switch;
  }
 
+ if (giop_thread_io() && ent->cnx->parent.timeout_mutex) {
+ g_mutex_lock (ent->cnx->parent.timeout_mutex);
+ if (ent->cnx->parent.timeout_status == LINK_TIMEOUT_UNKNOWN) {
+ link_io_thread_remove_timeout (ent->cnx->parent.timeout_source_id);
+ ent->cnx->parent.timeout_source_id = 0;
+ ent->cnx->parent.timeout_status = LINK_TIMEOUT_NO;
+ } else if (ent->cnx->parent.timeout_status == LINK_TIMEOUT_YES)
+ *timeout = TRUE;
+ g_mutex_unlock (ent->cnx->parent.timeout_mutex);
+ }
+
  giop_thread_queue_tail_wakeup (tdata);
  giop_recv_list_destroy_queue_entry (ent);
 
@@ -1355,6 +1355,72 @@
  return TRUE;
 }
 
+struct timeout_thread_data {
+ GIOPThread *tdata;
+ LinkConnection *lcnx;
+};
+
+static gboolean
+giop_timeout(gpointer data)
+{
+ gboolean retv = FALSE;
+ LinkConnection *lcnx = ((struct timeout_thread_data*)data)->lcnx;
+ GIOPThread *tdata =  ((struct timeout_thread_data*)data)->tdata;
+
+ g_assert (lcnx->timeout_mutex);
+
+ g_mutex_lock (lcnx->timeout_mutex);
+ if (lcnx->timeout_status == LINK_TIMEOUT_UNKNOWN) {
+ lcnx->timeout_source_id = 0;
+ lcnx->timeout_status = LINK_TIMEOUT_YES;
+ } else {
+ g_mutex_unlock (lcnx->timeout_mutex);
+ retv = TRUE; // do not remove the source - the one who sets timeout_status will do that
+ goto out;
+ }
+ g_mutex_unlock (lcnx->timeout_mutex);
+
+ link_connection_state_changed (lcnx, LINK_TIMEOUT);
+
+ g_mutex_lock (tdata->lock); /* ent_lock */
+ giop_incoming_signal_T (tdata, GIOP_CLOSECONNECTION);
+ g_mutex_unlock (tdata->lock); /* ent_lock */
+
+out:
+ g_object_unref (lcnx);
+ g_free (data);
+
+ return retv;
+}
+
+void
+giop_timeout_add(GIOPConnection *cnx)
+{
+ struct timeout_thread_data *data = NULL;
+ LinkConnection *lcnx = LINK_CONNECTION (cnx);
+ GSource *timeout_source = NULL;
+
+ if (!giop_thread_io ())
+ return;
+ if (!lcnx->timeout_msec)
+ return;
+
+ g_object_ref (lcnx);
+
+ if (!lcnx->timeout_mutex)
+ lcnx->timeout_mutex = g_mutex_new ();
+
+ g_mutex_lock (lcnx->timeout_mutex);
+ lcnx->timeout_status = LINK_TIMEOUT_UNKNOWN;
+ g_mutex_unlock (lcnx->timeout_mutex);
+
+ data = g_new0 (struct timeout_thread_data, 1);
+ data->tdata = giop_thread_self ();
+ data->lcnx = lcnx;
+
+ lcnx->timeout_source_id = link_io_thread_add_timeout (lcnx->timeout_msec, giop_timeout, data);
+}
+
 GIOPRecvBuffer *
 giop_recv_buffer_use_buf (GIOPConnection *cnx)
 {
@@ -1372,4 +1438,3 @@
 
  return buf;
 }
-
Index: src/orb/GIOP/giop-connection.c
===================================================================
--- src/orb/GIOP/giop-connection.c (revision 2004)
+++ src/orb/GIOP/giop-connection.c (working copy)
@@ -108,6 +108,7 @@
  }
 }
 
+
 static void
 giop_connection_class_init (GIOPConnectionClass *klass)
 {
@@ -192,3 +193,9 @@
  return link_connection_try_reconnect (LINK_CONNECTION (cnx));
 }
 
+void
+giop_set_timeout (guint msec)
+{
+ link_set_timeout (msec);
+}
+
Index: src/orb/GIOP/giop-send-buffer.c
===================================================================
--- src/orb/GIOP/giop-send-buffer.c (revision 2004)
+++ src/orb/GIOP/giop-send-buffer.c (working copy)
@@ -45,6 +45,25 @@
 
 static const GIOP_AddressingDisposition giop_1_2_target_type = GIOP_KeyAddr;
 
+static gboolean
+giop_send_buffer_is_oneway(const GIOPSendBuffer *buf)
+{
+ g_assert (buf);
+
+ switch (buf->giop_version) {
+ case GIOP_1_0:
+ case GIOP_1_1:
+ return (buf->msg.u.request_1_0.response_expected ? FALSE : TRUE);
+ case GIOP_1_2:
+ return (buf->msg.u.request_1_2.response_flags ? FALSE : TRUE);
+ default:
+ break;
+ }
+ g_assert_not_reached();
+
+ return TRUE;
+}
+
 GIOPSendBuffer *
 giop_send_buffer_use_request (GIOPVersion giop_version,
       CORBA_unsigned_long request_id,
@@ -426,6 +445,7 @@
  gboolean        blocking)
 {
  int retval;
+ LinkConnection *lcnx = LINK_CONNECTION (cnx);
  static LinkWriteOpts *non_block = NULL;
 
  if (!non_block)
@@ -434,11 +454,17 @@
  /* FIXME: if a FRAGMENT, assert the 8 byte tail align,
    &&|| giop_send_buffer_align (buf, 8); */
 
- retval = link_connection_writev (
- (LinkConnection *) cnx, buf->iovecs,
- buf->num_used,
- blocking ? NULL : non_block);
+ if (g_thread_supported ()
+    && lcnx->timeout_msec
+    && !giop_send_buffer_is_oneway (buf)) {
+ giop_timeout_add (cnx);
+ }
 
+ retval = link_connection_writev (lcnx,
+ buf->iovecs,
+ buf->num_used,
+ blocking ? NULL : non_block);
+
  if (!blocking && retval == LINK_IO_QUEUED_DATA)
  retval = 0;
 
Index: linc2/include/linc/linc-connection.h
===================================================================
--- linc2/include/linc/linc-connection.h (revision 2004)
+++ linc2/include/linc/linc-connection.h (working copy)
@@ -39,7 +39,8 @@
 #define LINK_IS_CONNECTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LINK_TYPE_CONNECTION))
 #define LINK_IS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LINK_TYPE_CONNECTION))
 
-typedef enum { LINK_CONNECTING, LINK_CONNECTED, LINK_DISCONNECTED } LinkConnectionStatus;
+typedef enum { LINK_CONNECTING, LINK_CONNECTED, LINK_DISCONNECTED, LINK_TIMEOUT } LinkConnectionStatus;
+typedef enum { LINK_TIMEOUT_UNKNOWN, LINK_TIMEOUT_YES, LINK_TIMEOUT_NO } LinkTimeoutStatus;
 
 typedef struct _LinkWriteOpts         LinkWriteOpts;
 typedef struct _LinkConnectionPrivate LinkConnectionPrivate;
@@ -61,6 +62,11 @@
  LinkConnectionPrivate  *priv;
 
  GSList                 *idle_broken_callbacks;
+
+ GMutex                 *timeout_mutex;
+ guint                   timeout_msec;
+ guint                   timeout_source_id; // protected by timeout_mutex
+ LinkTimeoutStatus       timeout_status;    // protected by timeout_mutex
 } LinkConnection;
 
 typedef struct {
@@ -153,6 +159,9 @@
 
 void           link_connections_close            (void);
 
+/* set the link timeout in miliseconds */
+extern void link_set_timeout (guint msec);
+
 G_END_DECLS
 
 #endif /* _LINK_CONNECTION_H */
Index: linc2/include/linc/linc.h
===================================================================
--- linc2/include/linc/linc.h (revision 2004)
+++ linc2/include/linc/linc.h (working copy)
@@ -33,12 +33,17 @@
 guint      link_main_idle_add    (GSourceFunc function,
   gpointer    data);
 
-gboolean   link_wait             (void);
+void       link_wait             (void);
 void       link_signal           (void);
 
 gboolean   link_thread_io        (void);
 gboolean   link_thread_safe      (void);
 
+guint      link_io_thread_add_timeout    (guint       interval,
+  GSourceFunc function,
+  gpointer    data);
+void       link_io_thread_remove_timeout (guint source_id);
+
 #ifdef G_OS_WIN32
 void link_map_winsock_error_to_errno (void);
 #endif
Index: linc2/ChangeLog
===================================================================
--- linc2/ChangeLog (revision 2004)
+++ linc2/ChangeLog (working copy)
@@ -1,3 +1,29 @@
+2007-07-05  Jules Colding  <colding@...>
+
+ * src/linc-connection.c (link_connection_try_reconnect):
+ Added LINK_TIMEOUT to valid reconnect states.
+
+2007-06-19  Jules Colding  <colding@...>
+
+ * src/linc-connection.c (link_connection_init): Initialize
+ timeout members in the LinkConnection structure.
+ (link_set_timeout): New function to set the timeout value.
+
+2007-06-18  Jules Colding  <colding@...>
+
+ * src/linc-connection.c (link_connection_from_fd_T): Initiate
+ timeout members of the link connection iff:
+ 1) The connection is IPv4 or IPv6
+ 2) It is not a oneway
+ 3) The timeout parameter is non-zero
+
+ * include/linc/linc-connection.h (struct):
+ 1) timeout mutex
+ 2) timeout value in milliseconds
+ 3) timeout status
+
+ Furthermore declare link_set_timeout()
+
 ========================== ORBit2-2.14.8 ========================
 
 2007-02-27  Kjartan Maraas  <kmaraas@...>
Index: linc2/src/linc-debug.h
===================================================================
--- linc2/src/linc-debug.h (revision 2004)
+++ linc2/src/linc-debug.h (working copy)
@@ -25,6 +25,7 @@
 #  define STATE_NAME(s) (((s) == LINK_CONNECTED) ? "Connected" : \
  ((s) == LINK_CONNECTING) ? "Connecting" : \
  ((s) == LINK_DISCONNECTED) ? "Disconnected" : \
+ ((s) == LINK_TIMEOUT) ? "Timeout" : \
  "Invalid state")
 #  ifdef CONNECTION_DEBUG_FLAG
 extern gboolean link_connection_debug_flag;
Index: linc2/src/linc-connection.c
===================================================================
--- linc2/src/linc-connection.c (revision 2004)
+++ linc2/src/linc-connection.c (working copy)
@@ -27,6 +27,7 @@
 #include <linc/linc-connection.h>
 
 static GObjectClass *parent_class = NULL;
+static guint _link_timeout = 0;
 
 enum {
  BROKEN,
@@ -288,6 +289,7 @@
  break;
 
  case LINK_DISCONNECTED:
+ case LINK_TIMEOUT:
  link_source_remove (cnx);
  link_close_fd (cnx);
  queue_free (cnx);
@@ -440,6 +442,16 @@
  g_free (cnx->remote_serv_info);
  cnx->remote_serv_info = remote_serv_info;
 
+ switch (cnx->proto->family) {
+ case AF_INET:
+ case AF_INET6:
+ if (_link_timeout && !cnx->timeout_msec) /* this should'nt happen twice but I'm always paranoid... */
+ cnx->timeout_msec = _link_timeout;
+ break;
+ default:
+ break;
+ }
+
  d_printf ("Cnx from fd (%d) '%s', '%s', '%s'\n",
  fd, proto->name,
  remote_host_info ? remote_host_info : "<Null>",
@@ -635,10 +647,8 @@
 static LinkConnectionStatus
 link_connection_wait_connected_T (LinkConnection *cnx)
 {
- while (cnx && cnx->status == LINK_CONNECTING) {
- if (!link_wait ())
- link_connection_disconnect (cnx);
- }
+ while (cnx && cnx->status == LINK_CONNECTING)
+ link_wait ();
 
  return cnx ? cnx->status : LINK_DISCONNECTED;
 }
@@ -661,20 +671,21 @@
  cnx->inhibit_reconnect = FALSE;
  dispatch_callbacks_drop_lock (cnx);
  g_main_context_release (NULL);
- } else {
- if (!link_wait ()) {
- link_connection_disconnect (cnx);
- break;
- }
- }
+ } else
+ link_wait ();
  }
 
- if (cnx->status != LINK_DISCONNECTED)
- g_warning ("trying to re-connect connected cnx.");
- else
+ switch (cnx->status) {
+ case LINK_DISCONNECTED :
+ case LINK_TIMEOUT :
  link_connection_do_initiate
  (cnx, cnx->proto->name, cnx->remote_host_info,
  cnx->remote_serv_info, cnx->options);
+ break;
+ default :
+ g_warning ("trying to re-connect connected cnx.");
+ break;
+ }
 
  cnx->priv->was_disconnected = TRUE;
  status = link_connection_wait_connected_T (cnx);
@@ -1254,6 +1265,13 @@
 
  g_free (cnx->priv);
 
+ if (cnx->timeout_mutex)
+ g_mutex_free (cnx->timeout_mutex);
+
+ if (cnx->timeout_source_id)
+ link_io_thread_remove_timeout (cnx->timeout_source_id);
+
+
 #ifdef G_ENABLE_DEBUG
  g_assert (g_list_find(cnx_list, cnx) == NULL);
 #endif
@@ -1269,6 +1287,12 @@
  cnx->priv = g_new0 (LinkConnectionPrivate, 1);
  cnx->priv->fd = -1;
  cnx->priv->was_disconnected = FALSE;
+
+ cnx->timeout_mutex = NULL;
+ cnx->timeout_msec = 0;
+ cnx->timeout_source_id = 0;
+ cnx->timeout_status = LINK_TIMEOUT_UNKNOWN;
+
 #ifdef CONNECTION_DEBUG
  cnx->priv->total_read_bytes = 0;
  cnx->priv->total_written_bytes = 0;
@@ -1568,3 +1592,10 @@
 
  g_list_free (cnx);
 }
+
+void
+link_set_timeout (guint msec)
+{
+ _link_timeout = msec;
+}
+
Index: linc2/src/linc.c
===================================================================
--- linc2/src/linc.c (revision 2004)
+++ linc2/src/linc.c (working copy)
@@ -52,9 +52,6 @@
 SSL_CTX    *link_ssl_ctx;
 #endif
 
-/* max time to wait for the link condition to get signaled - 10 seconds */
-#define LINK_WAIT_TIMEOUT_USEC (10000000)
-
 static void link_dispatch_command (gpointer data, gboolean immediate);
 
 gboolean
@@ -537,28 +534,17 @@
  }
 }
 
-gboolean
+void
 link_wait (void)
 {
- GTimeVal gtime;
-
  if (!(link_is_thread_safe && link_is_io_in_thread)) {
  link_unlock ();
  link_main_iteration (TRUE);
  link_lock ();
  } else {
  g_assert (link_main_cond != NULL);
-
- g_get_current_time (>ime);
- g_time_val_add (>ime, LINK_WAIT_TIMEOUT_USEC);
- if (!g_cond_timed_wait (link_main_cond, link_main_lock, >ime)) {
- if (link_is_locked ())
- link_unlock ();
- return FALSE;
- }
+ g_cond_wait (link_main_cond, link_main_lock);
  }
-
- return TRUE;
 }
 
 
@@ -568,3 +554,37 @@
 {
  return link_mutex_is_locked (link_main_lock);
 }
+
+/* Hack */
+guint
+link_io_thread_add_timeout (guint       interval,
+                            GSourceFunc function,
+                            gpointer    data)
+{
+ guint id;
+ GSource *tsrc;
+
+ if (!link_thread_safe())
+ return 0;
+
+ tsrc = g_timeout_source_new (interval);
+ g_source_set_priority (tsrc, G_PRIORITY_HIGH_IDLE);
+ g_source_set_callback (tsrc, function, data, NULL);
+ g_source_set_can_recurse (tsrc, TRUE);
+ id = g_source_attach (tsrc, link_thread_context);
+ g_source_unref (tsrc);
+
+ return id;
+}
+
+void
+link_io_thread_remove_timeout (guint source_id)
+{
+ GSource *tsrc;
+
+ if (!source_id)
+ return;
+
+ tsrc = g_main_context_find_source_by_id (link_thread_context, source_id);
+ g_source_destroy (tsrc);
+}

Property changes on: test
___________________________________________________________________
Name: svn:ignore
   - Makefile
Makefile.in
.deps
.libs
*-stubs.c
*-skels.c
*-common.c
empty.h
echo.h
test1.h
*_built
test-any.h
ior-decode-2
test1
echo-client
echo-client-t
echo-server
test-any-client
test-any-server
empty-client
empty-server
dynany.h
test-dynany
*-imodule.c
ior
typelib-dump
test-mem
test-performance
test-giop
test-corbaloc

   + Makefile
Makefile.in
.deps
.libs
*-stubs.c
*-skels.c
*-common.c
empty.h
echo.h
test1.h
*_built
test-any.h
ior-decode-2
test1
echo-client
echo-client-t
echo-server
test-any-client
test-any-server
empty-client
empty-server
dynany.h
test-dynany
*-imodule.c
ior
typelib-dump
test-mem
test-performance
test-giop
test-corbaloc
*.iorfile
timeout.h
timeout-server
timeout-client



Index: test/timeout-client.c
===================================================================
--- test/timeout-client.c (revision 0)
+++ test/timeout-client.c (revision 0)
@@ -0,0 +1,298 @@
+/*
+ * CORBA GIOP timeout test
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Author: Jules Colding <colding@...>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include "timeout.h"
+
+/*
+ * This method will return an ORB which is so initialized
+ * as to set a specific GIOP timeout value.
+ *
+ * orb_name     : Name of return ORB or empty string
+ *
+ * timeout      : GIOP timeout in milliseconds
+ *
+ * Return value : Initialized ORB or CORBA::ORB::_nil()
+ *
+ */
+static CORBA_ORB
+create_timeout_orb(const char *orb_name,
+   const char *timeout,
+   CORBA_Environment *ev)
+{
+ CORBA_ORB orb = CORBA_OBJECT_NIL;
+ char timeout_str[128] = { '\0' };
+ int argc = 0;
+ char **argv = NULL;
+
+ // sanity checks
+ if (!orb_name)
+ return CORBA_OBJECT_NIL;
+ if (!timeout)
+ return CORBA_OBJECT_NIL;
+
+ snprintf (timeout_str, sizeof(timeout_str), "--GIOPTimeoutMSEC=%s", timeout);
+
+ argc = 7;
+ argv = (char**)malloc (sizeof(char*) * argc);
+ if (!argv)
+ return CORBA_OBJECT_NIL;
+ memset ((void*)argv, 0, argc);
+
+ //  dummy argument
+ argv[0] = "dummy";
+
+ // IPv4 - needed to interoperate with TAO
+ argv[1] = "--ORBIIOPIPv4=1";
+
+ // IPv6 - could be needed to interoperate with TAO
+ argv[2] = "--ORBIIOPIPv6=1";
+
+ // Explicitly force ORBit2 to be non-local
+ argv[3] = "--ORBLocalOnly=0";
+
+ // Force ORBit2 to use the IP address in the all generated IORs
+ argv[4] = "--ORBNetID=ipaddr";
+
+ // do not use sockets
+ argv[5] = "--ORBIIOPUNIX=0";
+
+ // Set a timeout limit for GIOP operations
+ argv[6] = timeout_str;
+
+
+ // initialize the ORB
+ orb = CORBA_ORB_init (&argc, argv, (char*)orb_name, ev);
+ if (ev->_major != CORBA_NO_EXCEPTION)
+ orb = CORBA_OBJECT_NIL;
+
+ free (argv);
+
+ return orb;
+}
+
+static CORBA_Object
+object_ref_from_file(CORBA_ORB orb,
+     gchar *filename,
+     CORBA_Environment *ev)
+{
+ CORBA_Object obj = CORBA_OBJECT_NIL;
+ CORBA_char *objref = NULL;
+ FILE *file = NULL;
+ struct stat st;
+ size_t c = 0;
+
+ file = g_fopen(filename, "r");
+ if (!file)
+ return CORBA_OBJECT_NIL;
+
+ if (g_stat(filename, &st))
+ goto out;
+
+ objref = g_malloc0((st.st_size) * sizeof(gchar));
+ if (!objref)
+ goto out;
+
+ // must work even if sizeof(char) != sizeof(CORBA_char) (should be impossible, I know, but bad things happen...)
+ c = fread((void*)objref, sizeof(CORBA_char), (size_t)(st.st_size/sizeof(CORBA_char)), file);
+ if (c != st.st_size)
+ goto out;
+
+ obj = (CORBA_Object)CORBA_ORB_string_to_object(orb, objref, ev);
+
+out:
+ g_free(objref);
+ fclose(file);
+
+ return obj;
+}
+
+static Timeout
+get_timeout_ref(CORBA_ORB orb)
+{
+ Timeout obj = CORBA_OBJECT_NIL;
+ CORBA_boolean cb = CORBA_FALSE;
+ CORBA_Environment ev[1];
+
+ CORBA_exception_init (ev);
+
+ obj = object_ref_from_file(orb, "./timeout-server.iorfile", ev);
+ if (ev->_major != CORBA_NO_EXCEPTION) {
+ g_error ("object_ref_from_file(): %s\n", CORBA_exception_id (ev));
+ obj = CORBA_OBJECT_NIL;
+ goto out;
+ }
+
+ cb = CORBA_Object_is_nil((CORBA_Object)obj, ev);
+ if (ev->_major != CORBA_NO_EXCEPTION) {
+ g_error ("create_timeout_orb(): %s\n", CORBA_exception_id (ev));
+ obj = CORBA_OBJECT_NIL;
+ goto out;
+ }
+ if (cb) {
+ g_error ("Could not get Timeout reference\n");
+ goto out;
+ }
+
+out:
+ CORBA_exception_free (ev);
+
+ return obj;
+}
+
+int
+main (int argc, char *argv[])
+{
+ Timeout timeout_obj = CORBA_OBJECT_NIL;
+ CORBA_Environment ev;
+ CORBA_ORB orb;
+ int retv = EXIT_SUCCESS;
+
+ g_print ("=======================================================================\n");
+ g_print ("                ***  Starting GIOP timeout tests  ***                  \n");
+ g_print ("=======================================================================\n");
+
+ CORBA_exception_init (&ev);
+
+ /* create timeout orb */
+ orb = create_timeout_orb ("orbit-io-thread", "2000", &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("create_timeout_orb(): %s\n", CORBA_exception_id (&ev));
+ retv = EXIT_FAILURE;
+ goto out;
+ }
+
+ /* get ref */
+ if (argc == 1)
+ timeout_obj = get_timeout_ref(orb);
+ else if (argc == 2)
+ timeout_obj = (Timeout)CORBA_ORB_string_to_object (orb, argv[1], &ev);
+ else {
+ g_print ("ERROR, usage: %s [ior]\n", argv[0]);
+ }
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("CORBA_ORB_string_to_object(): %s\n", CORBA_exception_id (&ev));
+ retv = EXIT_FAILURE;
+ goto out;
+ }
+
+ /*
+ * test GIOP timeout
+ */
+
+ g_print ("Provoking timeout exception... ");
+ Timeout_ping (timeout_obj, 3, &ev);
+ if (ev._major == CORBA_NO_EXCEPTION) {
+ g_error ("ERROR: Timeout exception expected\n");
+ retv = EXIT_FAILURE;
+ goto out;
+ } else {
+ if (strcmp (CORBA_exception_id (&ev), ex_CORBA_TIMEOUT)) {
+ g_error ("Timeout_ping(): %s\n", CORBA_exception_id (&ev));
+ retv = EXIT_FAILURE;
+ goto out;
+ }
+ }
+ g_print ("OK\n");
+
+ g_print ("Testing reacquired connection with no server delay... ");
+ Timeout_ping (timeout_obj, 0, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("Timeout_ping(): %s\n", CORBA_exception_id (&ev));
+ retv = EXIT_FAILURE;
+ goto out;
+ }
+ g_print ("OK\n");
+
+ /* test no timeout but with a small delay */
+ g_print ("Testing with small server delay... ");
+ Timeout_ping (timeout_obj, 1, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("Timeout_ping(): %s\n", CORBA_exception_id (&ev));
+ retv = EXIT_FAILURE;
+ goto out;
+ }
+ g_print ("OK\n");
+
+ g_print ("Provoking timeout exception... ");
+ Timeout_ping (timeout_obj, 3, &ev);
+ if (ev._major == CORBA_NO_EXCEPTION) {
+ g_error ("ERROR: Timeout exception expected\n");
+ retv = EXIT_FAILURE;
+ goto out;
+ } else {
+ if (strcmp (CORBA_exception_id (&ev), ex_CORBA_TIMEOUT)) {
+ g_error ("Timeout_ping(): %s\n", CORBA_exception_id (&ev));
+ retv = EXIT_FAILURE;
+ goto out;
+ }
+ }
+ g_print ("OK\n");
+
+ g_print ("Testing reacquired connection with no server delay... ");
+ Timeout_ping (timeout_obj, 0, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("Timeout_ping(): %s\n", CORBA_exception_id (&ev));
+ retv = EXIT_FAILURE;
+ goto out;
+ }
+ g_print ("OK\n");
+
+out:
+ g_print ("Shutting down GIOP timeout tests... ");
+
+ /* release object reference */
+ CORBA_Object_release(timeout_obj, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("CORBA_Object_release(): %s\n", CORBA_exception_id (&ev));
+ abort ();
+ }
+
+ /* shutdown ORB, shutdown IO channels */
+ CORBA_ORB_shutdown (orb, FALSE, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("CORBA_ORB_shutdown(): %s\n", CORBA_exception_id (&ev));
+ abort ();
+ }
+
+ /* destroy local ORB */
+ CORBA_ORB_destroy(orb, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("CORBA_ORB_destroy(): %s\n", CORBA_exception_id (&ev));
+ abort ();
+ }
+ CORBA_exception_free (&ev);
+
+ g_print ("OK\n");
+
+ g_print ("=======================================================================\n");
+ if (retv == EXIT_FAILURE)
+ g_error ("             ***  Some GIOP timeout tests failed  ***                  \n");
+ else
+ g_print ("            ***  All GIOP timeout tests successful  ***                \n");
+ g_print ("=======================================================================\n");
+
+ return retv;
+}
Index: test/timeout_impl.c
===================================================================
--- test/timeout_impl.c (revision 0)
+++ test/timeout_impl.c (revision 0)
@@ -0,0 +1,127 @@
+/* This is a template file generated by command */
+/* orbit-idl-2 --skeleton-impl timeout.idl */
+/* User must edit this file, inserting servant  */
+/* specific code between markers. */
+
+#include <unistd.h>
+#include "timeout.h"
+
+/*** App-specific servant structures ***/
+
+#if !defined(_typedef_impl_POA_Timeout_)
+#define _typedef_impl_POA_Timeout_ 1
+typedef struct {
+ POA_Timeout servant;
+ PortableServer_POA poa;
+ /* ------ add private attributes here ------ */
+ /* ------ ---------- end ------------ ------ */
+} impl_POA_Timeout;
+#endif
+
+
+/*** Implementation stub prototypes ***/
+
+#if !defined(_decl_impl_Timeout__destroy_)
+#define _decl_impl_Timeout__destroy_ 1
+static void impl_Timeout__destroy(impl_POA_Timeout *servant,
+  CORBA_Environment *ev);
+#endif
+
+#if !defined(_decl_impl_Timeout_ping_)
+#define _decl_impl_Timeout_ping_ 1
+static void
+impl_Timeout_ping(impl_POA_Timeout *servant,
+  const CORBA_unsigned_long delay_secs,
+  CORBA_Environment *ev);
+#endif
+
+
+/*** epv structures ***/
+
+#if !defined(_impl_Timeout_base_epv_)
+#define _impl_Timeout_base_epv_ 1
+static PortableServer_ServantBase__epv impl_Timeout_base_epv = {
+ NULL,             /* _private data */
+ (gpointer) & impl_Timeout__destroy, /* finalize routine */
+ NULL,             /* default_POA routine */
+};
+#endif
+
+#if !defined(_impl_Timeout_epv_)
+#define _impl_Timeout_epv_ 1
+static POA_Timeout__epv impl_Timeout_epv = {
+ NULL, /* _private */
+ (gpointer)&impl_Timeout_ping,
+};
+#endif
+
+
+/*** vepv structures ***/
+
+#if !defined(_impl_Timeout_vepv_)
+#define _impl_Timeout_vepv_ 1
+static POA_Timeout__vepv impl_Timeout_vepv = {
+ &impl_Timeout_base_epv,
+ &impl_Timeout_epv,
+};
+#endif
+
+
+/*** Stub implementations ***/
+
+#if !defined(_impl_Timeout__create_)
+#define _impl_Timeout__create_ 1
+static Timeout impl_Timeout__create(PortableServer_POA poa, CORBA_Environment *ev)
+{
+ Timeout retval;
+ impl_POA_Timeout *newservant;
+ PortableServer_ObjectId *objid;
+
+ newservant = g_new0(impl_POA_Timeout, 1);
+ newservant->servant.vepv = &impl_Timeout_vepv;
+ newservant->poa = (PortableServer_POA) CORBA_Object_duplicate((CORBA_Object)poa, ev);
+ POA_Timeout__init((PortableServer_Servant)newservant, ev);
+ /* Before servant is going to be activated all
+ * private attributes must be initialized.  */
+
+ /* ------ init private attributes here ------ */
+ /* ------ ---------- end ------------- ------ */
+
+ objid = PortableServer_POA_activate_object(poa, newservant, ev);
+ CORBA_free(objid);
+ retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
+
+ return retval;
+}
+#endif
+
+#if !defined(_impl_Timeout__destroy_)
+#define _impl_Timeout__destroy_ 1
+static void
+impl_Timeout__destroy(impl_POA_Timeout *servant, CORBA_Environment *ev)
+{
+ CORBA_Object_release ((CORBA_Object) servant->poa, ev);
+
+ /* No further remote method calls are delegated to
+ * servant and you may free your private attributes. */
+ /* ------ free private attributes here ------ */
+ /* ------ ---------- end ------------- ------ */
+
+ POA_Timeout__fini((PortableServer_Servant)servant, ev);
+
+ g_free (servant);
+}
+#endif
+
+#if !defined(_impl_Timeout_ping_)
+#define _impl_Timeout_ping_ 1
+static void
+impl_Timeout_ping(impl_POA_Timeout *servant,
+  const CORBA_unsigned_long delay_secs,
+  CORBA_Environment *ev)
+{
+ /* ------   insert method code here   ------ */
+ sleep(delay_secs);
+ /* ------ ---------- end ------------ ------ */
+}
+#endif
Index: test/timeout.idl
===================================================================
--- test/timeout.idl (revision 0)
+++ test/timeout.idl (revision 0)
@@ -0,0 +1,3 @@
+interface Timeout {
+ void ping(in unsigned long delay_secs);
+};
Index: test/timeout-server.c
===================================================================
--- test/timeout-server.c (revision 0)
+++ test/timeout-server.c (revision 0)
@@ -0,0 +1,199 @@
+/*
+ * CORBA GIOP timeout test
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Author: Jules Colding <colding@...>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+
+#include "timeout_impl.c"
+
+/*
+ * This method will return an ORB which is so initialized
+ * as support IPv4 IORs
+ *
+ * orb_name     : Name of return ORB or empty string
+ *
+ * Return value : Initialized ORB or CORBA::ORB::_nil()
+ *
+ */
+static CORBA_ORB
+create_ipv4_orb(const char *orb_name,
+ CORBA_Environment *ev)
+{
+ CORBA_ORB orb = CORBA_OBJECT_NIL;
+ int argc = 0;
+ char **argv = NULL;
+
+ // sanity checks
+ if (!orb_name)
+ return CORBA_OBJECT_NIL;
+
+ argc = 6;
+ argv = (char**)malloc (sizeof(char*) * argc);
+ if (!argv)
+ return CORBA_OBJECT_NIL;
+ memset ((void*)argv, 0, argc);
+
+ //  dummy argument
+ argv[0] = "dummy";
+
+ // IPv4 - needed to interoperate with TAO
+ argv[1] = "--ORBIIOPIPv4=1";
+
+ // IPv6 - could be needed to interoperate with TAO
+ argv[2] = "--ORBIIOPIPv6=1";
+
+ // Explicitly force ORBit2 to be non-local
+ argv[3] = "--ORBLocalOnly=0";
+
+ // Force ORBit2 to use the IP address in the all generated IORs
+ argv[4] = "--ORBNetID=ipaddr";
+
+ // do not use sockets
+ argv[5] = "--ORBIIOPUNIX=0";
+
+ // initialize the ORB
+ orb = CORBA_ORB_init (&argc, argv, (char*)orb_name, ev);
+ if (ev->_major != CORBA_NO_EXCEPTION)
+ orb = CORBA_OBJECT_NIL;
+
+ free (argv);
+
+ return orb;
+}
+
+int
+main (int argc, char *argv[])
+{
+ PortableServer_ObjectId *objid = NULL;
+ PortableServer_POAManager mgr;
+ CORBA_Environment ev;
+ CORBA_ORB orb = CORBA_OBJECT_NIL;
+ PortableServer_POA poa = CORBA_OBJECT_NIL;
+ Timeout servant = CORBA_OBJECT_NIL;
+ FILE *iorfile;
+ char *ior;
+ int retv = EXIT_FAILURE;
+
+ signal(SIGINT, exit);
+ signal(SIGTERM, exit);
+
+ CORBA_exception_init (&ev);
+
+ /* create IPv4 orb */
+ orb = create_ipv4_orb ("orbit-io-thread", &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("create_ipv4_orb(): %s\n", CORBA_exception_id (&ev));
+ goto out;
+ }
+
+ /* get root poa */
+ poa = (PortableServer_POA)CORBA_ORB_resolve_initial_references (orb, "RootPOA", &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("create_ipv4_orb(): %s\n", CORBA_exception_id (&ev));
+ goto out;
+ }
+
+ /* activate root poa */
+ mgr = PortableServer_POA__get_the_POAManager (poa, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("PortableServer_POA__get_the_POAManager(): %s\n", CORBA_exception_id (&ev));
+ goto out;
+ }
+
+ PortableServer_POAManager_activate (mgr, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("PortableServer_POAManager_activate(): %s\n", CORBA_exception_id (&ev));
+ goto out;
+ }
+
+ CORBA_Object_release ((CORBA_Object)mgr, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("CORBA_Object_release(): %s\n", CORBA_exception_id (&ev));
+ goto out;
+ }
+
+ /* get corba object */
+ servant = impl_Timeout__create (poa, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("CORBA_Object_release(): %s\n", CORBA_exception_id (&ev));
+ goto out;
+ }
+
+ ior = CORBA_ORB_object_to_string (orb, servant, &ev);
+ iorfile = fopen ("timeout-server.iorfile", "w");
+ fprintf (iorfile, "%s\n", ior);
+ fclose (iorfile);
+ CORBA_free (ior);
+
+ CORBA_ORB_run (orb, &ev);
+
+ objid = PortableServer_POA_reference_to_id (poa, (CORBA_Object)servant, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("Exception caught from reference_to_id() - exiting");
+ if (objid)
+ CORBA_free(objid);
+ goto out;
+ }
+
+ PortableServer_POA_deactivate_object (poa, objid, &ev);
+ CORBA_free(objid);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("Exception caught from deactivate_object() - exiting");
+ goto out;
+ }
+
+ CORBA_Object_release ((CORBA_Object)servant, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("Exception caught from release() - exiting");
+ goto out;
+ }
+
+ PortableServer_POA_destroy (poa, TRUE, FALSE, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("Exception caught from destroy() - exiting");
+ goto out;
+ }
+
+ CORBA_Object_release ((CORBA_Object)poa, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("Exception caught from release() - exiting");
+ goto out;
+ }
+
+ /* ORB: tear down the ORB */
+ if (CORBA_OBJECT_NIL != orb) {
+ CORBA_ORB_destroy (orb, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("Exception caught from destroy() - exiting");
+ goto out;
+ }
+ CORBA_Object_release ((CORBA_Object) orb, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_error ("Exception caught from release() - exiting");
+ goto out;
+ }
+ }
+
+ retv = EXIT_SUCCESS;
+out:
+ return retv;
+}
Index: test/everything/test.sh
===================================================================
--- test/everything/test.sh (revision 2004)
+++ test/everything/test.sh (working copy)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 # This is a generic script for firing up a server, waiting for it to write
-# its stringified IOR to a file, then firing up a server
+# its stringified IOR to a file, then firing up a client
 
 if test "z$ORBIT_TMPDIR" = "z"; then
  ORBIT_TMPDIR="/tmp/orbit-$USER/tst"
Index: test/everything/client.c
===================================================================
--- test/everything/client.c (revision 2004)
+++ test/everything/client.c (working copy)
@@ -2034,6 +2034,7 @@
 
 
  test_PingPongServer_pingPong (r_objref, l_objref, 64, ev);
+ d_print (CORBA_exception_id (ev));
  g_assert (ev->_major == CORBA_NO_EXCEPTION);
 
  d_print ("Testing ping pong reg / lookup ...\n");
Index: test/timeout.sh
===================================================================
--- test/timeout.sh (revision 0)
+++ test/timeout.sh (revision 0)
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# This will test GIOP timeouts
+
+echo "Running timeout server..."
+./timeout-server &
+
+sleep 1
+
+echo "Running timeout client..."
+./timeout-client
+retv=$?
+
+
+killall lt-timeout-server
+
+exit $retv

Property changes on: test/timeout.sh
___________________________________________________________________
Name: svn:executable
   + *

Index: test/Makefile.am
===================================================================
--- test/Makefile.am (revision 2004)
+++ test/Makefile.am (working copy)
@@ -14,11 +14,12 @@
 noinst_PROGRAMS=test1 \
  echo-client echo-client-t echo-server \
  empty-client empty-server \
- test-any-client test-any-server
+ test-any-client test-any-server \
+ timeout-client timeout-server
 
 check_PROGRAMS = test-dynany test-mem test-performance test-giop test-corbaloc
 
-TESTS = $(check_PROGRAMS)
+TESTS =  timeout.sh $(check_PROGRAMS)
 
 LDADD = $(top_builddir)/src/orb/libORBit-2.la $(ORBIT_LIBS)
 
@@ -50,6 +51,11 @@
 empty_server_SOURCES=empty-server.c $(EMPTY_IDLOUT)
 $(srcdir)/empty-client.c $(srcdir)/empty-server.c: empty.h
 
+TIMEOUT_IDLOUT=timeout.h timeout-common.c timeout-stubs.c timeout-skels.c
+timeout_client_SOURCES=timeout-client.c $(TIMEOUT_IDLOUT)
+timeout_server_SOURCES=timeout-server.c $(TIMEOUT_IDLOUT)
+$(srcdir)/timeout-client.c $(srcdir)/timeout-server.c: timeout.h
+
 IDLOUT=test1-stubs.c test1-skels.c test1-common.c test1.h
 test1_SOURCES=test1.c $(IDLOUT)
 $(srcdir)/test1.c: test1.h
@@ -65,7 +71,7 @@
 test_dynany_LDFLAGS=$(LIBM)
 
 IDL_FLAGS =  --showcpperrors
-IDL_FILES=echo.idl empty.idl test-any.idl test1.idl dynany.idl
+IDL_FILES=echo.idl empty.idl test-any.idl test1.idl dynany.idl timeout.idl
 include $(top_srcdir)/Makefile.shared
 
 BUILT_SOURCES =            \
@@ -73,7 +79,8 @@
  $(ECHO_IDLOUT)     \
  $(IDLOUT)          \
  $(TEST_ANY_IDLOUT) \
- $(DYNANY_IDLOUT)
+ $(DYNANY_IDLOUT)   \
+ $(TIMEOUT_IDLOUT)
 
 CLEANFILES = $(BUILT_SOURCES)
 EXTRA_DIST = $(IDL_FILES)
Index: include/orbit/GIOP/giop-connection.h
===================================================================
--- include/orbit/GIOP/giop-connection.h (revision 2004)
+++ include/orbit/GIOP/giop-connection.h (working copy)
@@ -53,6 +53,9 @@
 #define         giop_connection_ref(cnx)      link_connection_ref(cnx)
 #define         giop_connection_unref(cnx)    link_connection_unref(cnx)
 
+/* set the link timeout in milliseconds */
+extern void giop_set_timeout (guint msec);
+
 #endif /* ORBIT2_INTERNAL_API */
 
 G_END_DECLS
Index: include/orbit/GIOP/giop.h
===================================================================
--- include/orbit/GIOP/giop.h (revision 2004)
+++ include/orbit/GIOP/giop.h (working copy)
@@ -23,7 +23,6 @@
 gboolean    giop_thread_io         (void);
 GIOPThread *giop_thread_self       (void);
 void        giop_invoke_async      (GIOPMessageQueueEntry *ent);
-void        giop_recv_set_timeout  (const glong timeout);
 void        giop_recv_set_limit    (glong limit);
 glong       giop_recv_get_limit    (void);
 void        giop_incoming_signal_T (GIOPThread *tdata, GIOPMsgType t);
@@ -47,7 +46,6 @@
 gboolean    giop_thread_queue_empty_T    (GIOPThread *tdata);
 void        giop_thread_queue_tail_wakeup(GIOPThread *tdata);
 
-
 #endif /* ORBIT2_INTERNAL_API */
 
 G_END_DECLS
Index: include/orbit/GIOP/giop-types.h
===================================================================
--- include/orbit/GIOP/giop-types.h (revision 2004)
+++ include/orbit/GIOP/giop-types.h (working copy)
@@ -35,10 +35,8 @@
  gpointer dummy);
 };
 
-#define GIOP_INITIAL_TIMEOUT_LIMIT (30000000) /* 30 seconds */
+#define GIOP_INITIAL_MSG_SIZE_LIMIT (256*1024)
 
-#define GIOP_INITIAL_MSG_SIZE_LIMIT (256*1024) /* in bytes */
-
 typedef enum {
  GIOP_CONNECTION_SSL
 } GIOPConnectionOptions;
Index: include/orbit/GIOP/giop-recv-buffer.h
===================================================================
--- include/orbit/GIOP/giop-recv-buffer.h (revision 2004)
+++ include/orbit/GIOP/giop-recv-buffer.h (working copy)
@@ -74,7 +74,9 @@
 void                        giop_recv_list_zap              (GIOPConnection *cnx);
 gboolean                    giop_connection_handle_input    (LinkConnection *lcnx);
 void                        giop_connection_destroy_frags   (GIOPConnection *cnx);
+extern void                 giop_timeout_add                (GIOPConnection *cnx);
 
+
 #endif /* ORBIT2_INTERNAL_API */
 
 G_END_DECLS


_______________________________________________
orbit-list mailing list
orbit-list@...
http://mail.gnome.org/mailman/listinfo/orbit-list

Re: Resend of GIOP timeout patch

by michael meeks :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Thu, 2007-07-05 at 20:02 +0200, Jules Colding wrote:
> > OK, I'll put a modified echo test case into make check. Stay tuned.
>
> The attached patch works perfectly on Gentoo dual AMD64. Should I
> commit?

        Of course ;-) there is no need to ask, really.

        Regards,

                Michael.

--
 michael.meeks@...  <><, Pseudo Engineer, itinerant idiot


_______________________________________________
orbit-list mailing list
orbit-list@...
http://mail.gnome.org/mailman/listinfo/orbit-list

Re: Resend of GIOP timeout patch

by colding :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, 2007-07-05 at 20:48 +0100, Michael Meeks wrote:
> On Thu, 2007-07-05 at 20:02 +0200, Jules Colding wrote:
> > > OK, I'll put a modified echo test case into make check. Stay tuned.
> >
> > The attached patch works perfectly on Gentoo dual AMD64. Should I
> > commit?
>
> Of course ;-) there is no need to ask, really.

OK, thanks - committed.

Maybe this even warrants a new release?

Best regards,
  jules


_______________________________________________
orbit-list mailing list
orbit-list@...
http://mail.gnome.org/mailman/listinfo/orbit-list