From genevieve.leclerc@optelvision.com Thu Jun 7 17:05:43 2007 Return-Path: X-Original-To: orbit-list@gnome.org Delivered-To: orbit-list@gnome.org Received: from localhost (localhost.localdomain [127.0.0.1]) by menubar.gnome.org (Postfix) with ESMTP id 469603B0088 for ; Thu, 7 Jun 2007 17:05:43 -0400 (EDT) X-Virus-Scanned: by amavisd-new at gnome.org X-Spam-Flag: YES X-Spam-Score: 2.166 X-Spam-Level: ** X-Spam-Status: Yes, score=2.166 tagged_above=-999 required=2 tests=[BAYES_50=0.001, FORGED_RCVD_HELO=0.135, HTML_MESSAGE=0.001, HTML_TEXT_AFTER_BODY=0.115, HTML_TITLE_EMPTY=0.214, L_P0F_W=1.7] X-Amavis-OS-Fingerprint: Windows 2000 SP2+, XP SP1+ (seldom 98), (distance 17, link: ethernet/modem), [206.108.60.208] Received: from menubar.gnome.org ([127.0.0.1]) by localhost (menubar.gnome.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id mXLdHBdeaHSi for ; Thu, 7 Jun 2007 17:05:39 -0400 (EDT) Received: from mta02.oricom.ca (mta02.oricom.ca [206.108.60.208]) by menubar.gnome.org (Postfix) with ESMTP id 193263B03E2 for ; Thu, 7 Jun 2007 17:05:26 -0400 (EDT) Received: from mailmx.ocktober.net (gandalf.ocktober.com [208.111.80.227]) by mta02.oricom.ca (Rockliffe SMTPRA 7.0.3) with ESMTP id for ; Thu, 7 Jun 2007 17:05:24 -0400 Received: from [192.168.0.157] ([64.18.178.33]) by mailmx.ocktober.net (Ocktober Design Mail Server) with ASMTP (SSL) id 3Z128367 for ; Thu, 07 Jun 2007 17:05:23 -0400 Message-ID: <46687314.8090501@optelvision.com> Date: Thu, 07 Jun 2007 17:05:24 -0400 From: genevieve leclerc User-Agent: Thunderbird 1.5.0.12 (Windows/20070509) MIME-Version: 1.0 To: orbit-list@gnome.org Subject: I need help with name-resolve example Content-Type: multipart/alternative; boundary="------------040906060402030304020108" X-BeenThere: orbit-list@gnome.org X-Mailman-Version: 2.1.8 Precedence: list List-Id: ORBit CORBA implementation use & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 07 Jun 2007 21:05:43 -0000 This is a multi-part message in MIME format. --------------040906060402030304020108 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hello! I am having a problem with the name-resolve example found in the "http://www.gnome.org/projects/ORBit2/orbit-docs/orbit/index.html" page. I had not make any change to the source code, and just run the make command. But once I start the name-resolve-server I got this error: $ ./name-resolve-server Binding service reference at name service against id: Examples/NameResolve/Service ** ERROR **: failed binding of service IDL:omg.org/CORBA/INV_OBJREF:1.0 aborting... Aborted So, I run the application in debug mode and manage to find where the problem lay but I don't know what to do to solve this problem. The problem is in the name-resolve-server.c file at line 187 name_service = etk_get_name_service (global_orb, ev); After this instruction had run, name_service is a null pointer. So in the next instruction, line 190 etk_name_service_bind (name_service, servant, id, ev); etk_name_service_bind() throw an exception via ev. And this is the exception I get. If anybody got a clue why etk_get_name_service () returns null, I will appreciated help. Thank you Sorry for my bad English. Ge --------------040906060402030304020108 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit




  
  


Hello!

I am having a problem with the name-resolve example found in the "http://www.gnome.org/projects/ORBit2/orbit-docs/orbit/index.html" page.

I had not make any change to the source code, and just run the make command.

But once I start the name-resolve-server I got this error:

$ ./name-resolve-server

Binding service reference at name service against id: Examples/NameResolve/Service


** ERROR **: failed binding of service IDL:omg.org/CORBA/INV_OBJREF:1.0

aborting...

Aborted

So, I run the application in debug mode and manage to find where the problem lay but I don't know what to do to solve this problem.

The problem is in the name-resolve-server.c file at line 187

name_service = etk_get_name_service (global_orb, ev);

After this instruction had run, name_service is a null pointer.

So in the next instruction, line 190

etk_name_service_bind (name_service, servant, id, ev);

etk_name_service_bind() throw an exception via ev.

And this is the exception I get.

If anybody got a clue why etk_get_name_service () returns null, I will appreciated help.

Thank you

Sorry for my bad English.

Ge


--------------040906060402030304020108--
From michael@ximian.com  Tue Jun 12 05:02:33 2007
Return-Path: 
X-Original-To: orbit-list@gnome.org
Delivered-To: orbit-list@gnome.org
Received: from localhost (localhost.localdomain [127.0.0.1])
	by menubar.gnome.org (Postfix) with ESMTP id 6F1A83B0074
	for ; Tue, 12 Jun 2007 05:02:33 -0400 (EDT)
X-Virus-Scanned: by amavisd-new at gnome.org
X-Spam-Score: -1.685
X-Spam-Level: 
X-Spam-Status: No, score=-1.685 tagged_above=-999 required=2
	tests=[AWL=-0.710, BAYES_05=-1.11, FORGED_RCVD_HELO=0.135]
X-Amavis-OS-Fingerprint: Linux 2.6, seldom 2.4 (older, 4) (up: 10322 hrs),
	(distance 17, link: ethernet/modem), [195.135.221.2]
Received: from menubar.gnome.org ([127.0.0.1])
	by localhost (menubar.gnome.org [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id WJ7N6Oukzvv5 for ;
	Tue, 12 Jun 2007 05:02:28 -0400 (EDT)
Received: from emea5-mh.id5.novell.com (charybdis-ext.suse.de [195.135.221.2])
	by menubar.gnome.org (Postfix) with ESMTP id 35B3A3B00B8
	for ; Tue, 12 Jun 2007 05:02:27 -0400 (EDT)
Received: from [192.168.0.8] ([149.44.162.75])
	by emea5-mh.id5.novell.com with ESMTP (TLS encrypted);
	Tue, 12 Jun 2007 11:02:18 +0200
Subject: Re: [PATCH] Timeout support - Please review
From: Michael Meeks 
To: Jules Colding 
In-Reply-To: <1165238535.23034.40.camel@omc-2.omesc.com>
References: <1165238535.23034.40.camel@omc-2.omesc.com>
Content-Type: text/plain
Organization: Novell, Inc.
Date: Tue, 12 Jun 2007 10:02:13 +0100
Message-Id: <1181638933.21605.135.camel@localhost>
Mime-Version: 1.0
X-Mailer: Evolution 2.6.0 
Content-Transfer-Encoding: 7bit
Cc: ORBit2 
X-BeenThere: orbit-list@gnome.org
X-Mailman-Version: 2.1.8
Precedence: list
Reply-To: michael.meeks@novell.com
List-Id: ORBit CORBA implementation use & development 
List-Unsubscribe: ,
	
List-Archive: 
List-Post: 
List-Help: 
List-Subscribe: ,
	
X-List-Received-Date: Tue, 12 Jun 2007 09:02:33 -0000

Hi Jules,

On Mon, 2006-12-04 at 14:22 +0100, Jules Colding wrote:
> Any and all occurrences of g_cond_wait() has the potential to block
> forever if the remote server is physically disconnected or powered of.

	Urgh - but also, some methods take longer than 30 seconds to execute,
and will not respond in that time.

	Also - when you are debugging, it is extremely normal to want to pause
everything in the debugger to examine some interaction - and you don't
expect everything to fail in unpredictable (or even silent ways) when
you continue.

	So: can we do this for IPv4/6 connections only ? local unix 
	    socket connections have strong lifecycle guarentees and this
	    covers the desktop use-case nicely.

> +	* src/linc.c (link_wait): Do not wait forever for the link
> +	condition to get signaled.
.. 
> +				if (!g_cond_timed_wait (tdata->incoming, tdata->lock, ((0 < giop_initial_timeout_limit) ? &tval : NULL))) {
> +					*timeout = TRUE;
> +					break;

	So I'm convinced this code is in the wrong place - worse, the link_wait
function now -releases- a mutex it didn't take itself: which looks
horribly un-maintainable: who took that lock ? and worse doing:

	if (foo_is_locked())
		unlock_foo();

	is just grotesquely racey.

	So - IMHO, the -right- way to implement this is rather simpler:

	* in the IO thread, we need to add a simple 'timeout' source to
	  the glib mainloop, that will timeout after (however long) and
	  in this case just push a constructed CORBA_COMM exception into
	  a synthesised reply that we shove into the queue as normal:
	  thus signalling the waiting caller.

	Surely that is simpler, easier, touches just 1 place, and doesn't
introduce odd behavior ? :-)

	Thanks,

		Michael.

PS. if you really want patch review, can you CC me explicitly.
-- 
 michael.meeks@novell.com  <><, Pseudo Engineer, itinerant idiot


From colding@omesc.com  Tue Jun 12 05:41:10 2007
Return-Path: 
X-Original-To: orbit-list@gnome.org
Delivered-To: orbit-list@gnome.org
Received: from localhost (localhost.localdomain [127.0.0.1])
	by menubar.gnome.org (Postfix) with ESMTP id 20C143B01CC
	for ; Tue, 12 Jun 2007 05:41:10 -0400 (EDT)
X-Virus-Scanned: by amavisd-new at gnome.org
X-Spam-Score: -3.599
X-Spam-Level: 
X-Spam-Status: No, score=-3.599 tagged_above=-999 required=2
	tests=[BAYES_00=-2.599, L_P0F_Unix=-1]
X-Amavis-OS-Fingerprint: FreeBSD 6.x (1) (up: 4486 hrs), (distance 24, link:
	ethernet/modem), [85.218.129.4]
Received: from menubar.gnome.org ([127.0.0.1])
	by localhost (menubar.gnome.org [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id q5DV+5bM1qB2 for ;
	Tue, 12 Jun 2007 05:41:01 -0400 (EDT)
Received: from mail-smtp1.ode.cdnet.dk (mail-smtp1.ode.cdnet.dk [85.218.129.4])
	by menubar.gnome.org (Postfix) with ESMTP id 94C9B3B01BC
	for ; Tue, 12 Jun 2007 05:40:55 -0400 (EDT)
Received: from localhost (localhost [127.0.0.1])
	by mail-smtp1.ode.cdnet.dk (Postfix) with ESMTP id D88822A0C29;
	Tue, 12 Jun 2007 11:40:52 +0200 (CEST)
X-Virus-Scanned: amavisd-new at cdnet.dk
Received: from mail-smtp1.ode.cdnet.dk ([127.0.0.1])
	by localhost (mail-smtp1.ode.cdnet.dk [127.0.0.1]) (amavisd-new,
	port 10024)
	with ESMTP id iOU4IVTWxmhc; Tue, 12 Jun 2007 11:40:50 +0200 (CEST)
Received: from [192.168.0.2] (unknown [85.218.191.254])
	by mail-smtp1.ode.cdnet.dk (Postfix) with ESMTP id 8906E2A0C13;
	Tue, 12 Jun 2007 11:40:49 +0200 (CEST)
Subject: Re: [PATCH] Timeout support - Please review
From: Jules Colding 
To: michael.meeks@novell.com
In-Reply-To: <1181638933.21605.135.camel@localhost>
References: <1165238535.23034.40.camel@omc-2.omesc.com>
	<1181638933.21605.135.camel@localhost>
Content-Type: text/plain
Date: Tue, 12 Jun 2007 11:40:49 +0200
Message-Id: <1181641249.31908.24.camel@omc-2.omesc.com>
Mime-Version: 1.0
X-Mailer: Evolution 2.8.3 
Content-Transfer-Encoding: 7bit
Cc: ORBit2 
X-BeenThere: orbit-list@gnome.org
X-Mailman-Version: 2.1.8
Precedence: list
List-Id: ORBit CORBA implementation use & development 
List-Unsubscribe: ,
	
List-Archive: 
List-Post: 
List-Help: 
List-Subscribe: ,
	
X-List-Received-Date: Tue, 12 Jun 2007 09:41:10 -0000

Hi Michael,

On Tue, 2007-06-12 at 10:02 +0100, Michael Meeks wrote:
> On Mon, 2006-12-04 at 14:22 +0100, Jules Colding wrote:
> > Any and all occurrences of g_cond_wait() has the potential to block
> > forever if the remote server is physically disconnected or powered of.
> 
> 	Urgh - but also, some methods take longer than 30 seconds to execute,
> and will not respond in that time.

Yes, you are right.


> 	So: can we do this for IPv4/6 connections only ? local unix 
> 	    socket connections have strong lifecycle guarentees and this
> 	    covers the desktop use-case nicely.

Yes.


> > +	* src/linc.c (link_wait): Do not wait forever for the link
> > +	condition to get signaled.
> .. 
> > +				if (!g_cond_timed_wait (tdata->incoming, tdata->lock, ((0 < giop_initial_timeout_limit) ? &tval : NULL))) {
> > +					*timeout = TRUE;
> > +					break;
> 
> 	So I'm convinced this code is in the wrong place - worse, the link_wait
> function now -releases- a mutex it didn't take itself: which looks
> horribly un-maintainable: who took that lock ? and worse doing:
> 
> 	if (foo_is_locked())
> 		unlock_foo();
> 
> 	is just grotesquely racey.

Yes, I know. Despite my previous bragging about "flawless quality" I was
actually a little worried about this too...


> 	So - IMHO, the -right- way to implement this is rather simpler:
> 
> 	* in the IO thread, we need to add a simple 'timeout' source to
> 	  the glib mainloop, that will timeout after (however long) and
> 	  in this case just push a constructed CORBA_COMM exception into
> 	  a synthesised reply that we shove into the queue as normal:
> 	  thus signalling the waiting caller.
> 
> 	Surely that is simpler, easier, touches just 1 place, and doesn't
> introduce odd behavior ? :-)

Absolutely. I'll reverse my previous patch and look into this approach
instead. 

Stay tuned,
  jules



From genevieve.leclerc@optelvision.com  Tue Jun 12 14:56:16 2007
Return-Path: 
X-Original-To: orbit-list@gnome.org
Delivered-To: orbit-list@gnome.org
Received: from localhost (localhost.localdomain [127.0.0.1])
	by menubar.gnome.org (Postfix) with ESMTP id DE8BA3B00AD
	for ; Tue, 12 Jun 2007 14:56:16 -0400 (EDT)
X-Virus-Scanned: by amavisd-new at gnome.org
X-Spam-Score: 1.836
X-Spam-Level: *
X-Spam-Status: No, score=1.836 tagged_above=-999 required=2
	tests=[BAYES_50=0.001, FORGED_RCVD_HELO=0.135, L_P0F_W=1.7]
X-Amavis-OS-Fingerprint: Windows 2000 SP2+, XP SP1+ (seldom 98), (distance 17, 
	link: ethernet/modem), [206.108.60.207]
Received: from menubar.gnome.org ([127.0.0.1])
	by localhost (menubar.gnome.org [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id 4sZiiVBC7GDO for ;
	Tue, 12 Jun 2007 14:55:48 -0400 (EDT)
Received: from mta01.oricom.ca (mta01.oricom.ca [206.108.60.207])
	by menubar.gnome.org (Postfix) with ESMTP id 813BE3B022D
	for ; Tue, 12 Jun 2007 14:54:43 -0400 (EDT)
Received: from mailmx.ocktober.net (gandalf.ocktober.com [208.111.80.227]) by
	mta01.oricom.ca
	(Rockliffe SMTPRA 7.0.3) with ESMTP id 
	for ; Tue, 12 Jun 2007 14:54:40 -0400
Received: from [192.168.0.157] ([64.18.178.33])
	by mailmx.ocktober.net (Ocktober Design Mail Server) with ASMTP (SSL)
	id 3Z128367
	for ; Tue, 12 Jun 2007 14:54:41 -0400
Message-ID: <466EEBF0.3070904@optelvision.com>
Date: Tue, 12 Jun 2007 14:54:40 -0400
From: genevieve leclerc 
User-Agent: Thunderbird 1.5.0.12 (Windows/20070509)
MIME-Version: 1.0
To: orbit-list@gnome.org
Subject: Re: I need help with name-resolve example SOLVED
References: 
In-Reply-To: 
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
X-BeenThere: orbit-list@gnome.org
X-Mailman-Version: 2.1.8
Precedence: list
List-Id: ORBit CORBA implementation use & development 
List-Unsubscribe: ,
	
List-Archive: 
List-Post: 
List-Help: 
List-Subscribe: ,
	
X-List-Received-Date: Tue, 12 Jun 2007 18:56:17 -0000

Ok I manage to find the problem with the naming service, and I have now 
a working naming service.


Ge

From genevieve.leclerc@optelvision.com  Tue Jun 12 16:09:28 2007
Return-Path: 
X-Original-To: orbit-list@gnome.org
Delivered-To: orbit-list@gnome.org
Received: from localhost (localhost.localdomain [127.0.0.1])
	by menubar.gnome.org (Postfix) with ESMTP id 1A9913B00AD
	for ; Tue, 12 Jun 2007 16:09:28 -0400 (EDT)
X-Virus-Scanned: by amavisd-new at gnome.org
X-Spam-Score: 1.836
X-Spam-Level: *
X-Spam-Status: No, score=1.836 tagged_above=-999 required=2
	tests=[BAYES_50=0.001, FORGED_RCVD_HELO=0.135, L_P0F_W=1.7]
X-Amavis-OS-Fingerprint: Windows 2000 SP2+, XP SP1+ (seldom 98), (distance 17, 
	link: ethernet/modem), [206.108.60.208]
Received: from menubar.gnome.org ([127.0.0.1])
	by localhost (menubar.gnome.org [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id lE24yG5XKUdK for ;
	Tue, 12 Jun 2007 16:09:25 -0400 (EDT)
Received: from mta02.oricom.ca (mta02.oricom.ca [206.108.60.208])
	by menubar.gnome.org (Postfix) with ESMTP id ADF6D3B007B
	for ; Tue, 12 Jun 2007 16:09:25 -0400 (EDT)
Received: from mailmx.ocktober.net (gandalf.ocktober.com [208.111.80.227]) by
	mta02.oricom.ca
	(Rockliffe SMTPRA 7.0.3) with ESMTP id 
	for ; Tue, 12 Jun 2007 16:09:23 -0400
Received: from [192.168.0.157] ([64.18.178.33])
	by mailmx.ocktober.net (Ocktober Design Mail Server) with ASMTP (SSL)
	id 3Z128367
	for ; Tue, 12 Jun 2007 16:09:23 -0400
Message-ID: <466EFD72.5070503@optelvision.com>
Date: Tue, 12 Jun 2007 16:09:22 -0400
From: genevieve leclerc 
User-Agent: Thunderbird 1.5.0.12 (Windows/20070509)
MIME-Version: 1.0
To: orbit-list@gnome.org
Subject: Leak problems with name service
References: 
In-Reply-To: 
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
X-BeenThere: orbit-list@gnome.org
X-Mailman-Version: 2.1.8
Precedence: list
List-Id: ORBit CORBA implementation use & development 
List-Unsubscribe: ,
	
List-Archive: 
List-Post: 
List-Help: 
List-Subscribe: ,
	
X-List-Received-Date: Tue, 12 Jun 2007 20:09:28 -0000

Hello everybody !

I manage to make the name-resolve example to work.
But I have a warning that bugs me because I don't want leaks in my program.

Moreover, the warning seems to cause an error.

When I stop the server or the client, I got the same warning and error 
messages:

$ ./name-resolve-server -ORBInitRef NameService=`cat name-service-ior`
Binding service reference at name service against id: 
Examples/NameResolve/Service

 >> Ceci est un test

** (process:7483): WARNING **: ORB: a total of 1 refs to ORB objects 
were leaked

** ERROR **: failed cleanup IDL:omg.org/CORBA/FREE_MEM:1.0
aborting...
Aborted

If anybody has an idea what cause my ORB to leaks I will be happy to hear it

Thanks

Ge
From colding@omesc.com  Thu Jun 21 07:51:40 2007
Return-Path: 
X-Original-To: orbit-list@gnome.org
Delivered-To: orbit-list@gnome.org
Received: from localhost (localhost.localdomain [127.0.0.1])
	by menubar.gnome.org (Postfix) with ESMTP id 161C43B0181
	for ; Thu, 21 Jun 2007 07:51:40 -0400 (EDT)
X-Virus-Scanned: by amavisd-new at gnome.org
X-Spam-Score: -3.522
X-Spam-Level: 
X-Spam-Status: No, score=-3.522 tagged_above=-999 required=2
	tests=[BAYES_00=-2.599, L_P0F_Unix=-1, TW_CN=0.077]
X-Amavis-OS-Fingerprint: FreeBSD 6.x (1) (up: 5267 hrs), (distance 25, link:
	ethernet/modem), [85.218.129.6]
Received: from menubar.gnome.org ([127.0.0.1])
	by localhost (menubar.gnome.org [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id Jc5EEz3YvM-e for ;
	Thu, 21 Jun 2007 07:51:35 -0400 (EDT)
Received: from mail-smtp3.ode.cdnet.dk (mail-smtp3.ode.cdnet.dk [85.218.129.6])
	by menubar.gnome.org (Postfix) with ESMTP id 0C7873B00F8
	for ; Thu, 21 Jun 2007 07:51:34 -0400 (EDT)
Received: from localhost (localhost [127.0.0.1])
	by mail-smtp3.ode.cdnet.dk (Postfix) with ESMTP id 6716422802D;
	Thu, 21 Jun 2007 13:51:32 +0200 (CEST)
X-Virus-Scanned: amavisd-new at cdnet.dk
Received: from mail-smtp3.ode.cdnet.dk ([127.0.0.1])
	by localhost (mail-smtp3.ode.cdnet.dk [127.0.0.1]) (amavisd-new,
	port 10024)
	with ESMTP id r2YLs+3qyDBc; Thu, 21 Jun 2007 13:51:29 +0200 (CEST)
Received: from [192.168.0.2] (unknown [85.218.191.254])
	by mail-smtp3.ode.cdnet.dk (Postfix) with ESMTP id 12C9C228013;
	Thu, 21 Jun 2007 13:51:29 +0200 (CEST)
Subject: New GIOP timeout patch - please review
From: Jules Colding 
To: Michael Meeks , ORBit2 
Content-Type: text/plain
Date: Thu, 21 Jun 2007 13:51:28 +0200
Message-Id: <1182426688.5074.176.camel@omc-2.omesc.com>
Mime-Version: 1.0
X-Mailer: Evolution 2.8.3 
Content-Transfer-Encoding: 7bit
X-BeenThere: orbit-list@gnome.org
X-Mailman-Version: 2.1.8
Precedence: list
List-Id: ORBit CORBA implementation use & development 
List-Unsubscribe: ,
	
List-Archive: 
List-Post: 
List-Help: 
List-Subscribe: ,
	
X-List-Received-Date: Thu, 21 Jun 2007 11:51:40 -0000

Hi all,

I've reverted my previous timeout approach following well deserved
criticism from Michael. This new approach seems to do the right thing
and I've tested it with a modified echo client/server. Explanation and
patch below.

Please comment.

Thanks,
  jules
 


The patch does the following:

0) The old timeout patch is reverted.

1) The timeout value is initialized in ORBit_ORB_start_servers().
Explicitly setting the value to 0 (zero) will disable timeout
altogether. The default value is 60 seconds.

2) The timeout value is a guint. I've added support for guint ORB
options.

3) Timeout helper members has been added to the LinkConnection
structure. This includes a timeout GMutex, a new link enum status member
and the timeout value in milliseconds.

4) These timeout members are initialized from there NIL state to
something that will result in an effective timeout on the individual
connection. This happens iff these statements hold true:

        a) The connection is IPv4 or IPv6
        b) The timeout member value is non-zero

This initialization happens in link_connection_from_fd_T().

5) A timeout thread is effectively launched in giop_send_buffer_write()
but only if the connection is not a oneway.

6) The timeout thread function will set the link state to LINK_TIMEOUT
and signal the GCond that giop_recv_buffer_get() waits on. 

7) ORBit_small_invoke_stub() will push a timeout exception down the line
upon learning from giop_recv_buffer_get() that the connection is timed
out.


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)
@@ -686,26 +686,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 +709,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 +719,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 +727,13 @@
 			goto thread_switch;
 	}
 
+	g_mutex_lock (ent->cnx->parent.timeout_mutex);
+	if (ent->cnx->parent.timeout_status == LINK_TIMEOUT_UNKNOWN)
+		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 +1348,73 @@
 	return TRUE;
 }
 
+struct timeout_thread_data {
+	guint msec;
+	GIOPThread *tdata;
+	LinkConnection *lcnx;
+};
+
+static gpointer
+giop_timeout(gpointer data)
+{
+	guint msec =  ((struct timeout_thread_data*)data)->msec;
+	LinkConnection *lcnx = ((struct timeout_thread_data*)data)->lcnx;
+	GIOPThread *tdata =  ((struct timeout_thread_data*)data)->tdata;
+	struct timespec tv;
+
+	g_assert (lcnx->timeout_mutex);
+
+	tv.tv_sec = msec / 1000;
+	tv.tv_nsec = (msec - tv.tv_sec*1000) * 1000000;
+	
+	nanosleep (&tv, NULL);
+
+	g_mutex_lock (lcnx->timeout_mutex);
+	if (lcnx->timeout_status == LINK_TIMEOUT_UNKNOWN)
+		lcnx->timeout_status = LINK_TIMEOUT_YES;
+	else {
+		g_mutex_unlock (lcnx->timeout_mutex);
+		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 NULL;
+}
+
+void
+giop_timeout_add(GIOPConnection *cnx)
+{
+	struct timeout_thread_data *data = NULL;
+	LinkConnection *lcnx = LINK_CONNECTION (cnx);
+
+	if (!lcnx->timeout_msec) 
+		return;
+
+	g_object_ref (lcnx);
+
+	lcnx->timeout_mutex = g_mutex_new ();
+
+	data = g_new0 (struct timeout_thread_data, 1);
+	data->msec = lcnx->timeout_msec;
+	data->tdata = giop_thread_self ();
+	data->lcnx = lcnx;
+
+	g_thread_create (giop_timeout,
+			 (gpointer)data,
+			 FALSE,
+			 NULL);
+}
+
 GIOPRecvBuffer *
 giop_recv_buffer_use_buf (GIOPConnection *cnx)
 {
@@ -1372,4 +1432,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,10 @@
 	LinkConnectionPrivate  *priv;
 
 	GSList                 *idle_broken_callbacks;
+
+	GMutex                 *timeout_mutex;
+	guint                   timeout_msec;
+	LinkTimeoutStatus       timeout_status;;
 } LinkConnection;
 
 typedef struct {
@@ -153,6 +158,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,7 +33,7 @@
 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);
Index: linc2/ChangeLog
===================================================================
--- linc2/ChangeLog	(revision 2003)
+++ linc2/ChangeLog	(working copy)
@@ -1,3 +1,24 @@
+2007-06-19  Jules 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  
+
+	* 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  
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 
 
 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,19 @@
 	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_mutex = NULL;
+			cnx->timeout_msec = _link_timeout;
+			cnx->timeout_status = LINK_TIMEOUT_UNKNOWN;
+		}
+		break;
+	default:
+		break;
+	}
+
 	d_printf ("Cnx from fd (%d) '%s', '%s', '%s'\n",
 		 fd, proto->name, 
 		 remote_host_info ? remote_host_info : "",
@@ -635,10 +650,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 +674,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 +1263,9 @@
 
 	g_free (cnx->priv);
 
+	if (cnx->timeout_mutex)
+		g_mutex_free (cnx->timeout_mutex);
+
 #ifdef G_ENABLE_DEBUG
 	g_assert (g_list_find(cnx_list, cnx) == NULL);
 #endif
@@ -1269,6 +1281,11 @@
 	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_status = LINK_TIMEOUT_UNKNOWN;
+
 #ifdef CONNECTION_DEBUG
 	cnx->priv->total_read_bytes = 0;
 	cnx->priv->total_written_bytes = 0;
@@ -1568,3 +1585,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;
 }
 
 
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
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 2003)
+++ ChangeLog	(working copy)
@@ -1,3 +1,49 @@
+2007-06-18  Jules Colding  
+
+	* src/orb/GIOP/giop-send-buffer.c (giop_send_buffer_is_oneway): 
+	New function to tell if the connection is a oneway.
+	(giop_send_buffer_write): Will add a timeout for the connection 
+	iff the timeout value is non-zero and the connection isn't oneway.
+
+	* src/orb/GIOP/giop-connection.c (giop_set_timeout): New function 
+	to set the link timeout value.
+
+	* src/orb/GIOP/giop-recv-buffer.c (giop_recv_buffer_get): 
+	1) Handle the LINK_TIMEOUT connection status. 
+	2) Added new function parameter to communicate the timeout 
+	   status to callers. 
+	(giop_timeout_add): New function to add a timeout thread.
+	(giop_timeout): Timeout thread function. Will wait using nanosleep 
+	until the timeout expires. Will change the link state 
+	to LINK_TIMEOUT and signal wait condition.
+
+	* src/orb/orb-core/corba-object.c (ORBit_try_connection_T): 
+	Handle a timed out link just like a disconnected link.
+
+	* src/orb/orb-core/corba-orb.c: The ORB command line option: 
+
+	   GIOPTimeoutLimit
+
+	is no more. It has been changed into:
+
+	   GIOPTimeoutMSEC - IPv4/6 timeout limit in milliseconds 
+
+	It defaults to 60 seconds. This options controls the timeout 
+	limit for GIOP connections, but only for IPv4 and IPv6 
+	connections. Setting it to zero will explicitly disable any 
+	timeout control.
+
+2007-06-13  Jules Colding  
+
+	* src/orb/util/orbit-options.c (ORBit_option_set): Support parsing 
+	unsigned long option values.
+
+	* src/orb/util/orbit-options.h (enum): Added support for 
+	unsigned long option values.
+
+	* Reverted previous GIOP timeout patch after having discussed
+	my flawed approach with Michael.
+
 2007-03-18  Brian Cameron  
 
 	* linc2/src/linc-protocols.c: Now always set the


From gjc@inescporto.pt  Thu Jun 21 08:10:37 2007
Return-Path: 
X-Original-To: orbit-list@gnome.org
Delivered-To: orbit-list@gnome.org
Received: from localhost (localhost.localdomain [127.0.0.1])
	by menubar.gnome.org (Postfix) with ESMTP id 0A4203B019B
	for ; Thu, 21 Jun 2007 08:10:35 -0400 (EDT)
X-Virus-Scanned: by amavisd-new at gnome.org
X-Spam-Score: -2.38
X-Spam-Level: 
X-Spam-Status: No, score=-2.38 tagged_above=-999 required=2 tests=[AWL=0.008, 
	BAYES_00=-2.599, FORGED_RCVD_HELO=0.135, SPF_PASS=-0.001,
	TW_CN=0.077]
X-Amavis-OS-Fingerprint: Linux 2.6, seldom 2.4 (older, 4) (up: 6664 hrs),
	(distance 21, link: ethernet/modem), [192.35.246.13]
Received: from menubar.gnome.org ([127.0.0.1])
	by localhost (menubar.gnome.org [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id PCrcN7JwIoN2 for ;
	Thu, 21 Jun 2007 08:10:29 -0400 (EDT)
Received: from pepe.inescn.pt (pepe.inescn.pt [192.35.246.13])
	by menubar.gnome.org (Postfix) with ESMTP id 6260D3B0189
	for ; Thu, 21 Jun 2007 08:10:27 -0400 (EDT)
Received: from localhost (pepe.inescn.pt [127.0.0.1])
	by pepe.inescn.pt (8.13.8/8.13.8/1) with ESMTP id l5LCAOlM004612;
	Thu, 21 Jun 2007 13:10:24 +0100
X-Virus-Scanned: amavisd-new at inescporto.pt
Received: from pepe.inescn.pt ([127.0.0.1])
	by localhost (pepe.inescn.pt [127.0.0.1]) (amavisd-new, port 10024)
	with LMTP id 8H9R-vWVFgvO; Thu, 21 Jun 2007 13:09:55 +0100 (WEST)
Received: from pong.inescporto.pt (pong.inescn.pt [194.117.26.74])
	by pepe.inescn.pt (8.13.8/8.13.8/9) with ESMTP id l5LC8hgX004527;
	Thu, 21 Jun 2007 13:08:43 +0100
Received: from [127.0.0.1] (localhost.localdomain [127.0.0.1])
	by pong.inescporto.pt (Postfix) with ESMTP id 9B093C47;
	Thu, 21 Jun 2007 13:08:41 +0100 (WEST)
Subject: Re: New GIOP timeout patch - please review
From: "Gustavo J. A. M. Carneiro" 
To: Jules Colding 
In-Reply-To: <1182426688.5074.176.camel@omc-2.omesc.com>
References: <1182426688.5074.176.camel@omc-2.omesc.com>
Content-Type: text/plain
Organization: INESC Porto
Date: Thu, 21 Jun 2007 13:09:04 +0100
Message-Id: <1182427744.22854.2.camel@localhost.localdomain>
Mime-Version: 1.0
X-Mailer: Evolution 2.11.4 
Content-Transfer-Encoding: 7bit
Cc: ORBit2 , Michael Meeks 
X-BeenThere: orbit-list@gnome.org
X-Mailman-Version: 2.1.8
Precedence: list
List-Id: ORBit CORBA implementation use & development 
List-Unsubscribe: ,
	
List-Archive: 
List-Post: 
List-Help: 
List-Subscribe: ,
	
X-List-Received-Date: Thu, 21 Jun 2007 12:10:37 -0000

  Hi,

  I must say that launching a thread for each outoging call just to get
a timeout is way overkill.  The glib main loop, which i'm sure Link is
using, already supports timeouts in a much more efficient manner.

On Qui, 2007-06-21 at 13:51 +0200, Jules Colding wrote:
> Hi all,
> 
> I've reverted my previous timeout approach following well deserved
> criticism from Michael. This new approach seems to do the right thing
> and I've tested it with a modified echo client/server. Explanation and
> patch below.
> 
> Please comment.
> 
> Thanks,
>   jules
>  
> 
> 
> The patch does the following:
> 
> 0) The old timeout patch is reverted.
> 
> 1) The timeout value is initialized in ORBit_ORB_start_servers().
> Explicitly setting the value to 0 (zero) will disable timeout
> altogether. The default value is 60 seconds.
> 
> 2) The timeout value is a guint. I've added support for guint ORB
> options.
> 
> 3) Timeout helper members has been added to the LinkConnection
> structure. This includes a timeout GMutex, a new link enum status member
> and the timeout value in milliseconds.
> 
> 4) These timeout members are initialized from there NIL state to
> something that will result in an effective timeout on the individual
> connection. This happens iff these statements hold true:
> 
>         a) The connection is IPv4 or IPv6
>         b) The timeout member value is non-zero
> 
> This initialization happens in link_connection_from_fd_T().
> 
> 5) A timeout thread is effectively launched in giop_send_buffer_write()
> but only if the connection is not a oneway.
> 
> 6) The timeout thread function will set the link state to LINK_TIMEOUT
> and signal the GCond that giop_recv_buffer_get() waits on. 
> 
> 7) ORBit_small_invoke_stub() will push a timeout exception down the line
> upon learning from giop_recv_buffer_get() that the connection is timed
> out.
> 
> 
> 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)
> @@ -686,26 +686,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 +709,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 +719,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 +727,13 @@
>  			goto thread_switch;
>  	}
>  
> +	g_mutex_lock (ent->cnx->parent.timeout_mutex);
> +	if (ent->cnx->parent.timeout_status == LINK_TIMEOUT_UNKNOWN)
> +		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 +1348,73 @@
>  	return TRUE;
>  }
>  
> +struct timeout_thread_data {
> +	guint msec;
> +	GIOPThread *tdata;
> +	LinkConnection *lcnx;
> +};
> +
> +static gpointer
> +giop_timeout(gpointer data)
> +{
> +	guint msec =  ((struct timeout_thread_data*)data)->msec;
> +	LinkConnection *lcnx = ((struct timeout_thread_data*)data)->lcnx;
> +	GIOPThread *tdata =  ((struct timeout_thread_data*)data)->tdata;
> +	struct timespec tv;
> +
> +	g_assert (lcnx->timeout_mutex);
> +
> +	tv.tv_sec = msec / 1000;
> +	tv.tv_nsec = (msec - tv.tv_sec*1000) * 1000000;
> +	
> +	nanosleep (&tv, NULL);
> +
> +	g_mutex_lock (lcnx->timeout_mutex);
> +	if (lcnx->timeout_status == LINK_TIMEOUT_UNKNOWN)
> +		lcnx->timeout_status = LINK_TIMEOUT_YES;
> +	else {
> +		g_mutex_unlock (lcnx->timeout_mutex);
> +		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 NULL;
> +}
> +
> +void
> +giop_timeout_add(GIOPConnection *cnx)
> +{
> +	struct timeout_thread_data *data = NULL;
> +	LinkConnection *lcnx = LINK_CONNECTION (cnx);
> +
> +	if (!lcnx->timeout_msec) 
> +		return;
> +
> +	g_object_ref (lcnx);
> +
> +	lcnx->timeout_mutex = g_mutex_new ();
> +
> +	data = g_new0 (struct timeout_thread_data, 1);
> +	data->msec = lcnx->timeout_msec;
> +	data->tdata = giop_thread_self ();
> +	data->lcnx = lcnx;
> +
> +	g_thread_create (giop_timeout,
> +			 (gpointer)data,
> +			 FALSE,
> +			 NULL);
> +}
> +
>  GIOPRecvBuffer *
>  giop_recv_buffer_use_buf (GIOPConnection *cnx)
>  {
> @@ -1372,4 +1432,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,10 @@
>  	LinkConnectionPrivate  *priv;
>  
>  	GSList                 *idle_broken_callbacks;
> +
> +	GMutex                 *timeout_mutex;
> +	guint                   timeout_msec;
> +	LinkTimeoutStatus       timeout_status;;
>  } LinkConnection;
>  
>  typedef struct {
> @@ -153,6 +158,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,7 +33,7 @@
>  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);
> Index: linc2/ChangeLog
> ===================================================================
> --- linc2/ChangeLog	(revision 2003)
> +++ linc2/ChangeLog	(working copy)
> @@ -1,3 +1,24 @@
> +2007-06-19  Jules 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  
> +
> +	* 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  
> 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 
>  
>  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,19 @@
>  	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_mutex = NULL;
> +			cnx->timeout_msec = _link_timeout;
> +			cnx->timeout_status = LINK_TIMEOUT_UNKNOWN;
> +		}
> +		break;
> +	default:
> +		break;
> +	}
> +
>  	d_printf ("Cnx from fd (%d) '%s', '%s', '%s'\n",
>  		 fd, proto->name, 
>  		 remote_host_info ? remote_host_info : "",
> @@ -635,10 +650,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 +674,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 +1263,9 @@
>  
>  	g_free (cnx->priv);
>  
> +	if (cnx->timeout_mutex)
> +		g_mutex_free (cnx->timeout_mutex);
> +
>  #ifdef G_ENABLE_DEBUG
>  	g_assert (g_list_find(cnx_list, cnx) == NULL);
>  #endif
> @@ -1269,6 +1281,11 @@
>  	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_status = LINK_TIMEOUT_UNKNOWN;
> +
>  #ifdef CONNECTION_DEBUG
>  	cnx->priv->total_read_bytes = 0;
>  	cnx->priv->total_written_bytes = 0;
> @@ -1568,3 +1585,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;
>  }
>  
> 
> 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
> Index: ChangeLog
> ===================================================================
> --- ChangeLog	(revision 2003)
> +++ ChangeLog	(working copy)
> @@ -1,3 +1,49 @@
> +2007-06-18  Jules Colding  
> +
> +	* src/orb/GIOP/giop-send-buffer.c (giop_send_buffer_is_oneway): 
> +	New function to tell if the connection is a oneway.
> +	(giop_send_buffer_write): Will add a timeout for the connection 
> +	iff the timeout value is non-zero and the connection isn't oneway.
> +
> +	* src/orb/GIOP/giop-connection.c (giop_set_timeout): New function 
> +	to set the link timeout value.
> +
> +	* src/orb/GIOP/giop-recv-buffer.c (giop_recv_buffer_get): 
> +	1) Handle the LINK_TIMEOUT connection status. 
> +	2) Added new function parameter to communicate the timeout 
> +	   status to callers. 
> +	(giop_timeout_add): New function to add a timeout thread.
> +	(giop_timeout): Timeout thread function. Will wait using nanosleep 
> +	until the timeout expires. Will change the link state 
> +	to LINK_TIMEOUT and signal wait condition.
> +
> +	* src/orb/orb-core/corba-object.c (ORBit_try_connection_T): 
> +	Handle a timed out link just like a disconnected link.
> +
> +	* src/orb/orb-core/corba-orb.c: The ORB command line option: 
> +
> +	   GIOPTimeoutLimit
> +
> +	is no more. It has been changed into:
> +
> +	   GIOPTimeoutMSEC - IPv4/6 timeout limit in milliseconds 
> +
> +	It defaults to 60 seconds. This options controls the timeout 
> +	limit for GIOP connections, but only for IPv4 and IPv6 
> +	connections. Setting it to zero will explicitly disable any 
> +	timeout control.
> +
> +2007-06-13  Jules Colding  
> +
> +	* src/orb/util/orbit-options.c (ORBit_option_set): Support parsing 
> +	unsigned long option values.
> +
> +	* src/orb/util/orbit-options.h (enum): Added support for 
> +	unsigned long option values.
> +
> +	* Reverted previous GIOP timeout patch after having discussed
> +	my flawed approach with Michael.
> +
>  2007-03-18  Brian Cameron  
>  
>  	* linc2/src/linc-protocols.c: Now always set the
> 
> 
> _______________________________________________
> orbit-list mailing list
> orbit-list@gnome.org
> http://mail.gnome.org/mailman/listinfo/orbit-list
-- 
Gustavo J. A. M. Carneiro
 
"The universe is always one step beyond logic" -- Frank Herbert

From colding@omesc.com  Thu Jun 21 08:23:58 2007
Return-Path: 
X-Original-To: orbit-list@gnome.org
Delivered-To: orbit-list@gnome.org
Received: from localhost (localhost.localdomain [127.0.0.1])
	by menubar.gnome.org (Postfix) with ESMTP id 33D373B026D
	for ; Thu, 21 Jun 2007 08:23:58 -0400 (EDT)
X-Virus-Scanned: by amavisd-new at gnome.org
X-Spam-Score: -3.599
X-Spam-Level: 
X-Spam-Status: No, score=-3.599 tagged_above=-999 required=2
	tests=[BAYES_00=-2.599, L_P0F_Unix=-1]
X-Amavis-OS-Fingerprint: FreeBSD 6.x (1) (up: 5272 hrs), (distance 25, link:
	ethernet/modem), [85.218.129.6]
Received: from menubar.gnome.org ([127.0.0.1])
	by localhost (menubar.gnome.org [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id pGKkmKBHqbcE for ;
	Thu, 21 Jun 2007 08:23:56 -0400 (EDT)
Received: from mail-smtp3.ode.cdnet.dk (mail-smtp3.ode.cdnet.dk [85.218.129.6])
	by menubar.gnome.org (Postfix) with ESMTP id 8813D3B015B
	for ; Thu, 21 Jun 2007 08:23:56 -0400 (EDT)
Received: from localhost (localhost [127.0.0.1])
	by mail-smtp3.ode.cdnet.dk (Postfix) with ESMTP id AB077228034;
	Thu, 21 Jun 2007 14:23:54 +0200 (CEST)
X-Virus-Scanned: amavisd-new at cdnet.dk
Received: from mail-smtp3.ode.cdnet.dk ([127.0.0.1])
	by localhost (mail-smtp3.ode.cdnet.dk [127.0.0.1]) (amavisd-new,
	port 10024)
	with ESMTP id WTbHOdDlIiWs; Thu, 21 Jun 2007 14:23:51 +0200 (CEST)
Received: from [192.168.0.2] (unknown [85.218.191.254])
	by mail-smtp3.ode.cdnet.dk (Postfix) with ESMTP id BF6E7228033;
	Thu, 21 Jun 2007 14:23:51 +0200 (CEST)
Subject: Re: New GIOP timeout patch - please review
From: Jules Colding 
To: "Gustavo J. A. M. Carneiro" 
In-Reply-To: <1182427744.22854.2.camel@localhost.localdomain>
References: <1182426688.5074.176.camel@omc-2.omesc.com>
	<1182427744.22854.2.camel@localhost.localdomain>
Content-Type: text/plain
Date: Thu, 21 Jun 2007 14:23:51 +0200
Message-Id: <1182428631.5074.181.camel@omc-2.omesc.com>
Mime-Version: 1.0
X-Mailer: Evolution 2.8.3 
Content-Transfer-Encoding: 7bit
Cc: ORBit2 , Michael Meeks 
X-BeenThere: orbit-list@gnome.org
X-Mailman-Version: 2.1.8
Precedence: list
List-Id: ORBit CORBA implementation use & development 
List-Unsubscribe: ,
	
List-Archive: 
List-Post: 
List-Help: 
List-Subscribe: ,
	
X-List-Received-Date: Thu, 21 Jun 2007 12:23:58 -0000

On Thu, 2007-06-21 at 13:09 +0100, Gustavo J. A. M. Carneiro wrote:
>   Hi,
> 
>   I must say that launching a thread for each outoging call just to get
> a timeout is way overkill.  The glib main loop, which i'm sure Link is
> using, already supports timeouts in a much more efficient manner.

I've already tried that with no success. Not sure why it didn't work,
but my first set of patches used this approach. The timeout failed to
trigger.

-- 
  jules


From colding@omesc.com  Thu Jun 21 08:49:51 2007
Return-Path: 
X-Original-To: orbit-list@gnome.org
Delivered-To: orbit-list@gnome.org
Received: from localhost (localhost.localdomain [127.0.0.1])
	by menubar.gnome.org (Postfix) with ESMTP id 959B83B019B
	for ; Thu, 21 Jun 2007 08:49:51 -0400 (EDT)
X-Virus-Scanned: by amavisd-new at gnome.org
X-Spam-Score: -3.522
X-Spam-Level: 
X-Spam-Status: No, score=-3.522 tagged_above=-999 required=2
	tests=[BAYES_00=-2.599, L_P0F_Unix=-1, TW_CN=0.077]
X-Amavis-OS-Fingerprint: FreeBSD 6.x (1) (up: 5276 hrs), (distance 25, link:
	ethernet/modem), [85.218.129.6]
Received: from menubar.gnome.org ([127.0.0.1])
	by localhost (menubar.gnome.org [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id wl6R-I8m2wLP for ;
	Thu, 21 Jun 2007 08:49:47 -0400 (EDT)
Received: from mail-smtp3.ode.cdnet.dk (mail-smtp3.ode.cdnet.dk [85.218.129.6])
	by menubar.gnome.org (Postfix) with ESMTP id E89C63B021A
	for ; Thu, 21 Jun 2007 08:49:46 -0400 (EDT)
Received: from localhost (localhost [127.0.0.1])
	by mail-smtp3.ode.cdnet.dk (Postfix) with ESMTP id 31276228034;
	Thu, 21 Jun 2007 14:49:45 +0200 (CEST)
X-Virus-Scanned: amavisd-new at cdnet.dk
Received: from mail-smtp3.ode.cdnet.dk ([127.0.0.1])
	by localhost (mail-smtp3.ode.cdnet.dk [127.0.0.1]) (amavisd-new,
	port 10024)
	with ESMTP id J5ygQjeJv9wB; Thu, 21 Jun 2007 14:49:41 +0200 (CEST)
Received: from [192.168.0.2] (unknown [85.218.191.254])
	by mail-smtp3.ode.cdnet.dk (Postfix) with ESMTP id B7F6E22802B;
	Thu, 21 Jun 2007 14:49:41 +0200 (CEST)
Subject: Re: New GIOP timeout patch - please review
From: Jules Colding 
To: Michael Meeks 
In-Reply-To: <1182426688.5074.176.camel@omc-2.omesc.com>
References: <1182426688.5074.176.camel@omc-2.omesc.com>
Content-Type: text/plain
Date: Thu, 21 Jun 2007 14:49:41 +0200
Message-Id: <1182430181.5074.190.camel@omc-2.omesc.com>
Mime-Version: 1.0
X-Mailer: Evolution 2.8.3 
Content-Transfer-Encoding: 7bit
Cc: ORBit2 
X-BeenThere: orbit-list@gnome.org
X-Mailman-Version: 2.1.8
Precedence: list
List-Id: ORBit CORBA implementation use & development 
List-Unsubscribe: ,
	
List-Archive: 
List-Post: 
List-Help: 
List-Subscribe: ,
	
X-List-Received-Date: Thu, 21 Jun 2007 12:49:51 -0000

On Thu, 2007-06-21 at 13:51 +0200, Jules Colding wrote:
> Hi all,
> 
> I've reverted my previous timeout approach following well deserved
> criticism from Michael. This new approach seems to do the right thing
> and I've tested it with a modified echo client/server. Explanation and
> patch below.
> 
> Please comment.

As always... Just noticed two small and stupid bugs. Corrected patch
below.

Sorry,
  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)
@@ -686,26 +686,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 +709,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 +719,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 +727,15 @@
 			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)
+			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 +1350,74 @@
 	return TRUE;
 }
 
+struct timeout_thread_data {
+	guint msec;
+	GIOPThread *tdata;
+	LinkConnection *lcnx;
+};
+
+static gpointer
+giop_timeout(gpointer data)
+{
+	guint msec =  ((struct timeout_thread_data*)data)->msec;
+	LinkConnection *lcnx = ((struct timeout_thread_data*)data)->lcnx;
+	GIOPThread *tdata =  ((struct timeout_thread_data*)data)->tdata;
+	struct timespec tv;
+
+	g_assert (lcnx->timeout_mutex);
+
+	tv.tv_sec = msec / 1000;
+	tv.tv_nsec = (msec - tv.tv_sec*1000) * 1000000;
+	
+	nanosleep (&tv, NULL);
+
+	g_mutex_lock (lcnx->timeout_mutex);
+	if (lcnx->timeout_status == LINK_TIMEOUT_UNKNOWN)
+		lcnx->timeout_status = LINK_TIMEOUT_YES;
+	else {
+		g_mutex_unlock (lcnx->timeout_mutex);
+		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 NULL;
+}
+
+void
+giop_timeout_add(GIOPConnection *cnx)
+{
+	struct timeout_thread_data *data = NULL;
+	LinkConnection *lcnx = LINK_CONNECTION (cnx);
+
+	if (!lcnx->timeout_msec) 
+		return;
+
+	g_object_ref (lcnx);
+
+	if (!lcnx->timeout_mutex)
+		lcnx->timeout_mutex = g_mutex_new ();
+
+	data = g_new0 (struct timeout_thread_data, 1);
+	data->msec = lcnx->timeout_msec;
+	data->tdata = giop_thread_self ();
+	data->lcnx = lcnx;
+
+	g_thread_create (giop_timeout,
+			 (gpointer)data,
+			 FALSE,
+			 NULL);
+}
+
 GIOPRecvBuffer *
 giop_recv_buffer_use_buf (GIOPConnection *cnx)
 {
@@ -1372,4 +1435,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,10 @@
 	LinkConnectionPrivate  *priv;
 
 	GSList                 *idle_broken_callbacks;
+
+	GMutex                 *timeout_mutex;
+	guint                   timeout_msec;
+	LinkTimeoutStatus       timeout_status;;
 } LinkConnection;
 
 typedef struct {
@@ -153,6 +158,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,7 +33,7 @@
 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);
Index: linc2/ChangeLog
===================================================================
--- linc2/ChangeLog	(revision 2003)
+++ linc2/ChangeLog	(working copy)
@@ -1,3 +1,24 @@
+2007-06-19  Jules 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  
+
+	* 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  
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 
 
 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 : "",
@@ -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,9 @@
 
 	g_free (cnx->priv);
 
+	if (cnx->timeout_mutex)
+		g_mutex_free (cnx->timeout_mutex);
+
 #ifdef G_ENABLE_DEBUG
 	g_assert (g_list_find(cnx_list, cnx) == NULL);
 #endif
@@ -1269,6 +1278,11 @@
 	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_status = LINK_TIMEOUT_UNKNOWN;
+
 #ifdef CONNECTION_DEBUG
 	cnx->priv->total_read_bytes = 0;
 	cnx->priv->total_written_bytes = 0;
@@ -1568,3 +1582,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;
 }
 
 
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
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 2003)
+++ ChangeLog	(working copy)
@@ -1,3 +1,49 @@
+2007-06-18  Jules Colding  
+
+	* src/orb/GIOP/giop-send-buffer.c (giop_send_buffer_is_oneway): 
+	New function to tell if the connection is a oneway.
+	(giop_send_buffer_write): Will add a timeout for the connection 
+	iff the timeout value is non-zero and the connection isn't oneway.
+
+	* src/orb/GIOP/giop-connection.c (giop_set_timeout): New function 
+	to set the link timeout value.
+
+	* src/orb/GIOP/giop-recv-buffer.c (giop_recv_buffer_get): 
+	1) Handle the LINK_TIMEOUT connection status. 
+	2) Added new function parameter to communicate the timeout 
+	   status to callers. 
+	(giop_timeout_add): New function to add a timeout thread.
+	(giop_timeout): Timeout thread function. Will wait using nanosleep 
+	until the timeout expires. Will change the link state 
+	to LINK_TIMEOUT and signal wait condition.
+
+	* src/orb/orb-core/corba-object.c (ORBit_try_connection_T): 
+	Handle a timed out link just like a disconnected link.
+
+	* src/orb/orb-core/corba-orb.c: The ORB command line option: 
+
+	   GIOPTimeoutLimit
+
+	is no more. It has been changed into:
+
+	   GIOPTimeoutMSEC - IPv4/6 timeout limit in milliseconds 
+
+	It defaults to 60 seconds. This options controls the timeout 
+	limit for GIOP connections, but only for IPv4 and IPv6 
+	connections. Setting it to zero will explicitly disable any 
+	timeout control.
+
+2007-06-13  Jules Colding  
+
+	* src/orb/util/orbit-options.c (ORBit_option_set): Support parsing 
+	unsigned long option values.
+
+	* src/orb/util/orbit-options.h (enum): Added support for 
+	unsigned long option values.
+
+	* Reverted previous GIOP timeout patch after having discussed
+	my flawed approach with Michael.
+
 2007-03-18  Brian Cameron  
 
 	* linc2/src/linc-protocols.c: Now always set the


From colding@omesc.com  Thu Jun 21 09:01:41 2007
Return-Path: 
X-Original-To: orbit-list@gnome.org
Delivered-To: orbit-list@gnome.org
Received: from localhost (localhost.localdomain [127.0.0.1])
	by menubar.gnome.org (Postfix) with ESMTP id 5678C3B008C
	for ; Thu, 21 Jun 2007 09:01:41 -0400 (EDT)
X-Virus-Scanned: by amavisd-new at gnome.org
X-Spam-Score: -3.599
X-Spam-Level: 
X-Spam-Status: No, score=-3.599 tagged_above=-999 required=2
	tests=[BAYES_00=-2.599, L_P0F_Unix=-1]
X-Amavis-OS-Fingerprint: FreeBSD 6.x (1) (up: 6624 hrs), (distance 25, link:
	ethernet/modem), [85.218.129.4]
Received: from menubar.gnome.org ([127.0.0.1])
	by localhost (menubar.gnome.org [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id ev3TtmxQVD1L for ;
	Thu, 21 Jun 2007 09:01:37 -0400 (EDT)
Received: from mail-smtp1.ode.cdnet.dk (mail-smtp1.ode.cdnet.dk [85.218.129.4])
	by menubar.gnome.org (Postfix) with ESMTP id 8DD4E3B00EF
	for ; Thu, 21 Jun 2007 09:01:37 -0400 (EDT)
Received: from localhost (localhost [127.0.0.1])
	by mail-smtp1.ode.cdnet.dk (Postfix) with ESMTP id 311D82A0C1C;
	Thu, 21 Jun 2007 15:01:35 +0200 (CEST)
X-Virus-Scanned: amavisd-new at cdnet.dk
Received: from mail-smtp1.ode.cdnet.dk ([127.0.0.1])
	by localhost (mail-smtp1.ode.cdnet.dk [127.0.0.1]) (amavisd-new,
	port 10024)
	with ESMTP id QhYryHf1G-fO; Thu, 21 Jun 2007 15:01:32 +0200 (CEST)
Received: from [192.168.0.2] (unknown [85.218.191.254])
	by mail-smtp1.ode.cdnet.dk (Postfix) with ESMTP id 4FED32A0C3A;
	Thu, 21 Jun 2007 15:01:32 +0200 (CEST)
Subject: Re: New GIOP timeout patch - please review
From: Jules Colding 
To: "Gustavo J. A. M. Carneiro" 
In-Reply-To: <1182427744.22854.2.camel@localhost.localdomain>
References: <1182426688.5074.176.camel@omc-2.omesc.com>
	<1182427744.22854.2.camel@localhost.localdomain>
Content-Type: text/plain
Date: Thu, 21 Jun 2007 15:01:32 +0200
Message-Id: <1182430892.5074.194.camel@omc-2.omesc.com>
Mime-Version: 1.0
X-Mailer: Evolution 2.8.3 
Content-Transfer-Encoding: 7bit
Cc: ORBit2 , Michael Meeks 
X-BeenThere: orbit-list@gnome.org
X-Mailman-Version: 2.1.8
Precedence: list
List-Id: ORBit CORBA implementation use & development 
List-Unsubscribe: ,
	
List-Archive: 
List-Post: 
List-Help: 
List-Subscribe: ,
	
X-List-Received-Date: Thu, 21 Jun 2007 13:01:41 -0000

On Thu, 2007-06-21 at 13:09 +0100, Gustavo J. A. M. Carneiro wrote:
>   Hi,
> 
>   I must say that launching a thread for each outoging call just to get
> a timeout is way overkill.  

BTW, it is not for each and every outgoing call. It is only for
non-oneway IPV4 or IPv6 connections. Not for unix sockets and such.

-- 
  jules


From michael.meeks@novell.com  Thu Jun 21 11:10:24 2007
Return-Path: 
X-Original-To: orbit-list@gnome.org
Delivered-To: orbit-list@gnome.org
Received: from localhost (localhost.localdomain [127.0.0.1])
	by menubar.gnome.org (Postfix) with ESMTP id 64DD83B0259
	for ; Thu, 21 Jun 2007 11:10:24 -0400 (EDT)
X-Virus-Scanned: by amavisd-new at gnome.org
X-Spam-Score: -2.207
X-Spam-Level: 
X-Spam-Status: No, score=-2.207 tagged_above=-999 required=2
	tests=[AWL=-0.221, BAYES_00=-2.599, DATE_IN_PAST_03_06=0.478,
	FORGED_RCVD_HELO=0.135]
X-Amavis-OS-Fingerprint: Linux 2.6, seldom 2.4 (older, 4) (up: 66 hrs),
	(distance 17, link: ethernet/modem), [195.135.221.2]
Received: from menubar.gnome.org ([127.0.0.1])
	by localhost (menubar.gnome.org [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id 7H2+apaTZAT9 for ;
	Thu, 21 Jun 2007 11:10:22 -0400 (EDT)
Received: from emea5-mh.id5.novell.com (charybdis-ext.suse.de [195.135.221.2])
	by menubar.gnome.org (Postfix) with ESMTP id 1ABA83B01C5
	for ; Thu, 21 Jun 2007 11:10:19 -0400 (EDT)
Received: from [192.168.1.100] ([149.44.162.75])
	by emea5-mh.id5.novell.com with ESMTP (TLS encrypted);
	Thu, 21 Jun 2007 17:09:52 +0200
Subject: Re: New GIOP timeout patch - please review
From: Michael Meeks 
To: Jules Colding 
In-Reply-To: <1182430181.5074.190.camel@omc-2.omesc.com>
References: <1182426688.5074.176.camel@omc-2.omesc.com>
	<1182430181.5074.190.camel@omc-2.omesc.com>
Content-Type: text/plain
Organization: Novell, Inc.
Date: Thu, 21 Jun 2007 12:46:23 +0100
Message-Id: <1182426383.3917.96.camel@localhost>
Mime-Version: 1.0
X-Mailer: Evolution 2.6.0 
Content-Transfer-Encoding: 7bit
Cc: ORBit2 
X-BeenThere: orbit-list@gnome.org
X-Mailman-Version: 2.1.8
Precedence: list
Reply-To: michael.meeks@novell.com
List-Id: ORBit CORBA implementation use & development 
List-Unsubscribe: ,
	
List-Archive: 
List-Post: 
List-Help: 
List-Subscribe: ,
	
X-List-Received-Date: Thu, 21 Jun 2007 15:10:24 -0000

Hi Jules,

On Thu, 2007-06-21 at 14:49 +0200, Jules Colding wrote:
> As always... Just noticed two small and stupid bugs. Corrected patch
> below.

	Sigh - so 1 new thread per IPv4 connection ? that will cripple Sun who
use IPv4/CORBA to do their Java a11y bridging stuff. We should only do
that as a stop-gap, and only if it's turned off by default for IPv4
users I think [ is that so ? ].

	-really- it would be way better to instrument your glib and find out
why the timeout thing is not getting called. -One- possibility may be
that you're not setting it to be a 'recursive' source (although perhaps
unlikely given the lack of re-enterancy there).

	HTH,

		Michael.

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


From colding@omesc.com  Fri Jun 22 08:19:04 2007
Return-Path: 
X-Original-To: orbit-list@gnome.org
Delivered-To: orbit-list@gnome.org
Received: from localhost (localhost.localdomain [127.0.0.1])
	by menubar.gnome.org (Postfix) with ESMTP id 312273B009A
	for ; Fri, 22 Jun 2007 08:19:04 -0400 (EDT)
X-Virus-Scanned: by amavisd-new at gnome.org
X-Spam-Score: -3.522
X-Spam-Level: 
X-Spam-Status: No, score=-3.522 tagged_above=-999 required=2
	tests=[BAYES_00=-2.599, L_P0F_Unix=-1, TW_CN=0.077]
X-Amavis-OS-Fingerprint: FreeBSD 6.x (1) (up: 6851 hrs), (distance 25, link:
	ethernet/modem), [85.218.129.4]
Received: from menubar.gnome.org ([127.0.0.1])
	by localhost (menubar.gnome.org [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id vXLaJhWd0C4i for ;
	Fri, 22 Jun 2007 08:18:58 -0400 (EDT)
Received: from mail-smtp1.ode.cdnet.dk (mail-smtp1.ode.cdnet.dk [85.218.129.4])
	by menubar.gnome.org (Postfix) with ESMTP id 6D9153B0070
	for ; Fri, 22 Jun 2007 08:18:57 -0400 (EDT)
Received: from localhost (localhost [127.0.0.1])
	by mail-smtp1.ode.cdnet.dk (Postfix) with ESMTP id C4E972A0C32;
	Fri, 22 Jun 2007 14:18:54 +0200 (CEST)
X-Virus-Scanned: amavisd-new at cdnet.dk
Received: from mail-smtp1.ode.cdnet.dk ([127.0.0.1])
	by localhost (mail-smtp1.ode.cdnet.dk [127.0.0.1]) (amavisd-new,
	port 10024)
	with ESMTP id Nu0Q4oOt6Cz9; Fri, 22 Jun 2007 14:18:49 +0200 (CEST)
Received: from [192.168.0.2] (unknown [85.218.191.254])
	by mail-smtp1.ode.cdnet.dk (Postfix) with ESMTP id 4090F2A0C36;
	Fri, 22 Jun 2007 14:18:49 +0200 (CEST)
Subject: Re: New GIOP timeout patch - please review
From: Jules Colding 
To: michael.meeks@novell.com
In-Reply-To: <1182426383.3917.96.camel@localhost>
References: <1182426688.5074.176.camel@omc-2.omesc.com>
	<1182430181.5074.190.camel@omc-2.omesc.com>
	<1182426383.3917.96.camel@localhost>
Content-Type: multipart/mixed; boundary="=-PsrMOXKckbDNUaiUF2ll"
Date: Fri, 22 Jun 2007 14:18:48 +0200
Message-Id: <1182514728.25157.55.camel@omc-2.omesc.com>
Mime-Version: 1.0
X-Mailer: Evolution 2.8.3 
Cc: ORBit2 ,
	"Gustavo J. A. M.  Carneiro" 
X-BeenThere: orbit-list@gnome.org
X-Mailman-Version: 2.1.8
Precedence: list
List-Id: ORBit CORBA implementation use & development 
List-Unsubscribe: ,
	
List-Archive: 
List-Post: 
List-Help: 
List-Subscribe: ,
	
X-List-Received-Date: Fri, 22 Jun 2007 12:19:04 -0000


--=-PsrMOXKckbDNUaiUF2ll
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Hi Michael,

On Thu, 2007-06-21 at 12:46 +0100, Michael Meeks wrote:
> Hi Jules,
> 
> On Thu, 2007-06-21 at 14:49 +0200, Jules Colding wrote:
> > As always... Just noticed two small and stupid bugs. Corrected patch
> > below.
> 
> 	Sigh - so 1 new thread per IPv4 connection ? that will cripple Sun who
> use IPv4/CORBA to do their Java a11y bridging stuff. We should only do
> that as a stop-gap, and only if it's turned off by default for IPv4
> users I think [ is that so ? ].

No, the default is 60 seconds. The reason is that it is currently
impossible to change ORB options if you are not the lucky one to call
ORB_init(). I could create a workaround, but that would add to the
external API, so I assumed that a long default would be the better
choice.


> 	-really- it would be way better to instrument your glib and find out
> why the timeout thing is not getting called. -One- possibility may be
> that you're not setting it to be a 'recursive' source (although perhaps
> unlikely given the lack of re-enterancy there).

I think that I need to crawl down into glib and take a look... My
current test patch is below as well as my modifications to the echo
client/server. The echo server must be executed as:

   ./echo-server --ORBIIOPIPv4=1 --ORBLocalOnly=0 --ORBIIOPUNIX=0

The client should be executed as:

   ./echo-client --GIOPTimeoutMSEC=3 $(cat echo-server.iorfile) 1

I've attache timeout.h which I use to adjust the sleep time in the
server. 

Any good ideas would be appreciated highly.

Best regards,
  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 
 #include 
 #include 
+#include 
+#include 
 
 #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,15 @@
 			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)
+			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 +1352,117 @@
 	return TRUE;
 }
 
+struct timeout_thread_data {
+	GIOPThread *tdata;
+	LinkConnection *lcnx;
+};
+
+/* static gpointer */
+/* giop_timeout(gpointer data) */
+/* { */
+/* 	LinkConnection *lcnx = ((struct timeout_thread_data*)data)->lcnx; */
+/* 	GIOPThread *tdata =  ((struct timeout_thread_data*)data)->tdata; */
+/* 	struct timespec tv; */
+
+/* 	g_assert (lcnx->timeout_mutex); */
+
+/* 	tv.tv_sec = lcnx->timeout_msec / 1000; */
+/* 	tv.tv_nsec = (lcnx->timeout_msec - tv.tv_sec*1000) * 1000000; */
+	
+/* 	nanosleep (&tv, NULL); */
+
+/* 	g_mutex_lock (lcnx->timeout_mutex); */
+/* 	if (lcnx->timeout_status == LINK_TIMEOUT_UNKNOWN) */
+/* 		lcnx->timeout_status = LINK_TIMEOUT_YES; */
+/* 	else { */
+/* 		g_mutex_unlock (lcnx->timeout_mutex); */
+/* 		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 NULL; */
+/* } */
+
+static gboolean
+giop_timeout(gpointer data)
+{
+	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_status = LINK_TIMEOUT_YES;
+	else {
+		g_mutex_unlock (lcnx->timeout_mutex);
+		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 FALSE;
+}
+
+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);
+
+/* 	g_thread_create (giop_timeout, */
+/* 			 (gpointer)data, */
+/* 			 FALSE, */
+/* 			 NULL); */
+
+	timeout_source = g_timeout_source_new (lcnx->timeout_msec);
+	g_source_set_priority (timeout_source, G_PRIORITY_HIGH_IDLE);
+	g_source_set_callback (timeout_source, giop_timeout, (gpointer)data, NULL);
+	g_source_set_can_recurse (timeout_source, TRUE);
+	g_source_attach (timeout_source, data->tdata->wake_context);
+	g_source_unref (timeout_source);
+}
+
 GIOPRecvBuffer *
 giop_recv_buffer_use_buf (GIOPConnection *cnx)
 {
@@ -1372,4 +1480,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,10 @@
 	LinkConnectionPrivate  *priv;
 
 	GSList                 *idle_broken_callbacks;
+
+	GMutex                 *timeout_mutex;
+	guint                   timeout_msec;
+	LinkTimeoutStatus       timeout_status;;
 } LinkConnection;
 
 typedef struct {
@@ -153,6 +158,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,7 +33,7 @@
 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);
Index: linc2/ChangeLog
===================================================================
--- linc2/ChangeLog	(revision 2003)
+++ linc2/ChangeLog	(working copy)
@@ -1,3 +1,24 @@
+2007-06-19  Jules 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  
+
+	* 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  
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 
 
 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 : "",
@@ -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,9 @@
 
 	g_free (cnx->priv);
 
+	if (cnx->timeout_mutex)
+		g_mutex_free (cnx->timeout_mutex);
+
 #ifdef G_ENABLE_DEBUG
 	g_assert (g_list_find(cnx_list, cnx) == NULL);
 #endif
@@ -1269,6 +1278,11 @@
 	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_status = LINK_TIMEOUT_UNKNOWN;
+
 #ifdef CONNECTION_DEBUG
 	cnx->priv->total_read_bytes = 0;
 	cnx->priv->total_written_bytes = 0;
@@ -1568,3 +1582,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;
 }
 
 
Index: test/echo-server.c
===================================================================
--- test/echo-server.c	(revision 2003)
+++ test/echo-server.c	(working copy)
@@ -40,7 +40,8 @@
 	signal(SIGTERM, exit);
 
 	CORBA_exception_init(&ev);
-	orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
+//	orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
+	orb = CORBA_ORB_init(&argc, argv, "orbit-io-thread", &ev);
 	g_assert(ev._major == CORBA_NO_EXCEPTION);
 
 	echo_srv_start_poa(orb, &ev);
Index: test/echo-srv.c
===================================================================
--- test/echo-srv.c	(revision 2003)
+++ test/echo-srv.c	(working copy)
@@ -22,8 +22,10 @@
 #include 
 #include 
 #include 
+#include 
 #include "echo.h"
 #include "echo-share.h"
+#include "timeout.h"
 
 /**
    This is used by echo-server.c and echo-local.c
@@ -47,7 +49,9 @@
 		g_message ("[server] %s", astring);
 
 	*outnum = rand() % 100;
-	
+
+	sleep(SLEEP);
+
 	return CORBA_Object_duplicate (the_echo_client, ev);
 }
 
Index: test/echo-client.c
===================================================================
--- test/echo-client.c	(revision 2003)
+++ test/echo-client.c	(working copy)
@@ -21,15 +21,24 @@
 #include 
 
 #include "echo.h"
+#include "timeout.h"
 
 
 #define ABORT_IF_EXCEPTION(_ev, _message)                    \
-if ((_ev)->_major != CORBA_NO_EXCEPTION) {                   \
-  g_error("%s: %s", _message, CORBA_exception_id (_ev));     \
+	if ((_ev) && (_ev)->_major != CORBA_NO_EXCEPTION) {	       \
+  g_error("%s: %s\n", _message, CORBA_exception_id (_ev));     \
   CORBA_exception_free (_ev);                                \
   abort();                                                   \
 }
 
+#define PRINT_EXCEPTION(_ev, _message) do { \
+		if (_ev) \
+			g_print("%s: %s\n", _message, CORBA_exception_id (_ev)); \
+		else \
+			g_print("No exception\n"); \
+	} while (0); 
+
+
 static Echo echo_client, bec;
 
 static gboolean echo_opt_quiet = FALSE;
@@ -45,7 +54,8 @@
 	int niters = 1000;
 
 	CORBA_exception_init(&ev);
-	orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
+//	orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
+	orb = CORBA_ORB_init(&argc, argv, "orbit-io-thread", &ev);
 
 	/* read IOR from command line as first argument */
 	if(argc < 2) {
@@ -73,32 +83,51 @@
 	for(i = 0; i < niters; i++) {
 		/* Method call without any argument, usefull to tell
 		 * lifeness */
-		Echo_doNothing(echo_client, &ev);
-		ABORT_IF_EXCEPTION (&ev, "service raised exception ");
+/* 		Echo_doNothing(echo_client, &ev); */
+/* 		ABORT_IF_EXCEPTION (&ev, "service raised exception "); */
 
 		/* Ask echo-service to print string 'buf' on console. The
 		 * service returns random double float value in 'vr' */
-		g_snprintf(buf, sizeof(buf), "Hello, world [%d]", i);
+/* 		g_snprintf(buf, sizeof(buf), "Hello, world [%d]", i); */
+/* 		bec = Echo_echoString(echo_client, buf, &rv, &ev); */
+/* 		ABORT_IF_EXCEPTION (&ev, "service raised exception "); */
+
+		/* Test the GIOP timeout functionality. The server must be started 
+		 * with "--GIOPTimeoutLimit=2000 --ORBIIOPIPv4=1" for this test to work. */
+		g_snprintf(buf, sizeof(buf), TIMEOUT_STR);
+		g_message("0");
 		bec = Echo_echoString(echo_client, buf, &rv, &ev);
-		ABORT_IF_EXCEPTION (&ev, "service raised exception ");
+		g_message("00");
+		if (ev._major != CORBA_NO_EXCEPTION) {
+			g_message("1");
+			PRINT_EXCEPTION (&ev, "Printing exception ");
+			g_message("2");
+			bec = CORBA_OBJECT_NIL;
+			g_message("3");
+		}
+		CORBA_exception_init(&ev);
+		g_message("A");
 
 		/* print random value generated by echo-service */
-		if ( !echo_opt_quiet )
-			g_message("[client] %g", rv);
+/* 		if ( !echo_opt_quiet ) */
+/* 			g_message("[client] %g", rv); */
 
 		/* Asynchronous/oneway method call, the function returns
 		 * immediately.  Usefull for log-message transfer */
-		Echo_doOneWay(echo_client, "log message ", &ev);
-		ABORT_IF_EXCEPTION (&ev, "service raised exception ");
+/* 		Echo_doOneWay(echo_client, "log message ", &ev); */
+/* 		ABORT_IF_EXCEPTION (&ev, "service raised exception "); */
 
 		/* release first object reference and use the new one for
 		 * next loop */
 		CORBA_Object_release(echo_client, &ev);
+		g_message("B");
 		ABORT_IF_EXCEPTION (&ev, "service raised exception ");
+		g_message("C");
 
 		/* swap object references */ 
 		echo_client = bec; bec = CORBA_OBJECT_NIL;
 	}
+	g_message("C");
     
 	/* release initial object reference */
 	CORBA_Object_release(echo_client, &ev);
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
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 2003)
+++ ChangeLog	(working copy)
@@ -1,3 +1,49 @@
+2007-06-18  Jules Colding  
+
+	* src/orb/GIOP/giop-send-buffer.c (giop_send_buffer_is_oneway): 
+	New function to tell if the connection is a oneway.
+	(giop_send_buffer_write): Will add a timeout for the connection 
+	iff the timeout value is non-zero and the connection isn't oneway.
+
+	* src/orb/GIOP/giop-connection.c (giop_set_timeout): New function 
+	to set the link timeout value.
+
+	* src/orb/GIOP/giop-recv-buffer.c (giop_recv_buffer_get): 
+	1) Handle the LINK_TIMEOUT connection status. 
+	2) Added new function parameter to communicate the timeout 
+	   status to callers. 
+	(giop_timeout_add): New function to add a timeout thread.
+	(giop_timeout): Timeout thread function. Will wait using nanosleep 
+	until the timeout expires. Will change the link state 
+	to LINK_TIMEOUT and signal wait condition.
+
+	* src/orb/orb-core/corba-object.c (ORBit_try_connection_T): 
+	Handle a timed out link just like a disconnected link.
+
+	* src/orb/orb-core/corba-orb.c: The ORB command line option: 
+
+	   GIOPTimeoutLimit
+
+	is no more. It has been changed into:
+
+	   GIOPTimeoutMSEC - IPv4/6 timeout limit in milliseconds 
+
+	It defaults to 60 seconds. This options controls the timeout 
+	limit for GIOP connections, but only for IPv4 and IPv6 
+	connections. Setting it to zero will explicitly disable any 
+	timeout control.
+
+2007-06-13  Jules Colding  
+
+	* src/orb/util/orbit-options.c (ORBit_option_set): Support parsing 
+	unsigned long option values.
+
+	* src/orb/util/orbit-options.h (enum): Added support for 
+	unsigned long option values.
+
+	* Reverted previous GIOP timeout patch after having discussed
+	my flawed approach with Michael.
+
 2007-03-18  Brian Cameron  
 
 	* linc2/src/linc-protocols.c: Now always set the




--=-PsrMOXKckbDNUaiUF2ll
Content-Disposition: attachment; filename=timeout.h
Content-Type: text/x-chdr; name=timeout.h; charset=UTF-8
Content-Transfer-Encoding: 7bit

/*
 * CORBA timeout test values
 *
 * 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 
 */

#ifndef timeout_H
#define timeout_H (1)

#define TIMEOUT (2)
#define SLEEP   (TIMEOUT+1)
#define TIMEOUT_STR "test_timeout"

#endif

--=-PsrMOXKckbDNUaiUF2ll--

From colding@omesc.com  Fri Jun 22 10:06:17 2007
Return-Path: 
X-Original-To: orbit-list@gnome.org
Delivered-To: orbit-list@gnome.org
Received: from localhost (localhost.localdomain [127.0.0.1])
	by menubar.gnome.org (Postfix) with ESMTP id 4278D3B00C8
	for ; Fri, 22 Jun 2007 10:06:17 -0400 (EDT)
X-Virus-Scanned: by amavisd-new at gnome.org
X-Spam-Score: -3.599
X-Spam-Level: 
X-Spam-Status: No, score=-3.599 tagged_above=-999 required=2
	tests=[BAYES_00=-2.599, L_P0F_Unix=-1]
X-Amavis-OS-Fingerprint: FreeBSD 6.x (1) (up: 6869 hrs), (distance 25, link:
	ethernet/modem), [85.218.129.4]
Received: from menubar.gnome.org ([127.0.0.1])
	by localhost (menubar.gnome.org [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id Gkg2XmlHpCrD for ;
	Fri, 22 Jun 2007 10:06:15 -0400 (EDT)
Received: from mail-smtp1.ode.cdnet.dk (mail-smtp1.ode.cdnet.dk [85.218.129.4])
	by menubar.gnome.org (Postfix) with ESMTP id 3686B3B009A
	for ; Fri, 22 Jun 2007 10:06:15 -0400 (EDT)
Received: from localhost (localhost [127.0.0.1])
	by mail-smtp1.ode.cdnet.dk (Postfix) with ESMTP id 01F0B2A0C3C;
	Fri, 22 Jun 2007 16:06:13 +0200 (CEST)
X-Virus-Scanned: amavisd-new at cdnet.dk
Received: from mail-smtp1.ode.cdnet.dk ([127.0.0.1])
	by localhost (mail-smtp1.ode.cdnet.dk [127.0.0.1]) (amavisd-new,
	port 10024)
	with ESMTP id 2SYbHC50-LP2; Fri, 22 Jun 2007 16:06:10 +0200 (CEST)
Received: from [192.168.0.2] (unknown [85.218.191.254])
	by mail-smtp1.ode.cdnet.dk (Postfix) with ESMTP id EED842A0C12;
	Fri, 22 Jun 2007 16:06:09 +0200 (CEST)
Subject: Re: New GIOP timeout patch - please review
From: Jules Colding 
To: michael.meeks@novell.com
In-Reply-To: <1182514728.25157.55.camel@omc-2.omesc.com>
References: <1182426688.5074.176.camel@omc-2.omesc.com>
	<1182430181.5074.190.camel@omc-2.omesc.com>
	<1182426383.3917.96.camel@localhost>
	<1182514728.25157.55.camel@omc-2.omesc.com>
Content-Type: text/plain
Date: Fri, 22 Jun 2007 16:06:09 +0200
Message-Id: <1182521169.25157.64.camel@omc-2.omesc.com>
Mime-Version: 1.0
X-Mailer: Evolution 2.8.3 
Content-Transfer-Encoding: 7bit
Cc: ORBit2 ,
	"Gustavo J. A. M.  Carneiro" 
X-BeenThere: orbit-list@gnome.org
X-Mailman-Version: 2.1.8
Precedence: list
List-Id: ORBit CORBA implementation use & development 
List-Unsubscribe: ,
	
List-Archive: 
List-Post: 
List-Help: 
List-Subscribe: ,
	
X-List-Received-Date: Fri, 22 Jun 2007 14:06:17 -0000

Hi,

On Fri, 2007-06-22 at 14:18 +0200, Jules Colding wrote:
> > 	-really- it would be way better to instrument your glib and find out
> > why the timeout thing is not getting called. -One- possibility may be
> > that you're not setting it to be a 'recursive' source (although perhaps
> > unlikely given the lack of re-enterancy there).
> 
> I think that I need to crawl down into glib and take a look... 

Sigh... I've been crawling all over the glib source. I can see that my
timeout source is being added to the context(s) but nothing happens.

I've tried the main context and the giop loop context but with equally
disappointing results.

Any advise/help/encouraging yells would be highly appreciated.


Best regards,
  jules


From gjc@inescporto.pt  Fri Jun 22 10:57:45 2007
Return-Path: 
X-Original-To: orbit-list@gnome.org
Delivered-To: orbit-list@gnome.org
Received: from localhost (localhost.localdomain [127.0.0.1])
	by menubar.gnome.org (Postfix) with ESMTP id C8B963B0096
	for ; Fri, 22 Jun 2007 10:57:45 -0400 (EDT)
X-Virus-Scanned: by amavisd-new at gnome.org
X-Spam-Score: -2.419
X-Spam-Level: 
X-Spam-Status: No, score=-2.419 tagged_above=-999 required=2 tests=[AWL=0.046, 
	BAYES_00=-2.599, FORGED_RCVD_HELO=0.135, SPF_PASS=-0.001]
X-Amavis-OS-Fingerprint: Linux 2.6, seldom 2.4 (older, 4) (up: 6932 hrs),
	(distance 21, link: ethernet/modem), [192.35.246.13]
Received: from menubar.gnome.org ([127.0.0.1])
	by localhost (menubar.gnome.org [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id BjxfHEFoL+l6 for ;
	Fri, 22 Jun 2007 10:57:42 -0400 (EDT)
Received: from pepe.inescn.pt (pepe.inescn.pt [192.35.246.13])
	by menubar.gnome.org (Postfix) with ESMTP id 60DBA3B0074
	for ; Fri, 22 Jun 2007 10:57:42 -0400 (EDT)
Received: from localhost (pepe.inescn.pt [127.0.0.1])
	by pepe.inescn.pt (8.13.8/8.13.8/1) with ESMTP id l5MEvdCb026535;
	Fri, 22 Jun 2007 15:57:39 +0100
X-Virus-Scanned: amavisd-new at inescporto.pt
Received: from pepe.inescn.pt ([127.0.0.1])
	by localhost (pepe.inescn.pt [127.0.0.1]) (amavisd-new, port 10024)
	with LMTP id 7hJg-EATOCID; Fri, 22 Jun 2007 15:57:18 +0100 (WEST)
Received: from pong.inescporto.pt (pong.inescn.pt [194.117.26.74])
	by pepe.inescn.pt (8.13.8/8.13.8/9) with ESMTP id l5MEYeoL025405;
	Fri, 22 Jun 2007 15:34:40 +0100
Received: from [194.117.26.60] (spectrum.inescn.pt [194.117.26.60])
	by pong.inescporto.pt (Postfix) with ESMTP id AE5DC19BB4D;
	Fri, 22 Jun 2007 15:34:40 +0100 (WEST)
Subject: Re: New GIOP timeout patch - please review
From: "Gustavo J. A. M. Carneiro" 
To: Jules Colding 
In-Reply-To: <1182521169.25157.64.camel@omc-2.omesc.com>
References: <1182426688.5074.176.camel@omc-2.omesc.com>
	<1182430181.5074.190.camel@omc-2.omesc.com>
	<1182426383.3917.96.camel@localhost>
	<1182514728.25157.55.camel@omc-2.omesc.com>
	<1182521169.25157.64.camel@omc-2.omesc.com>
Content-Type: text/plain
Organization: INESC Porto
Date: Fri, 22 Jun 2007 15:34:40 +0100
Message-Id: <1182522880.12892.22.camel@localhost>
Mime-Version: 1.0
X-Mailer: Evolution 2.10.1 
Content-Transfer-Encoding: 7bit
Cc: ORBit2 , michael.meeks@novell.com
X-BeenThere: orbit-list@gnome.org
X-Mailman-Version: 2.1.8
Precedence: list
List-Id: ORBit CORBA implementation use & development 
List-Unsubscribe: ,
	
List-Archive: 
List-Post: 
List-Help: 
List-Subscribe: ,
	
X-List-Received-Date: Fri, 22 Jun 2007 14:57:45 -0000

On Sex, 2007-06-22 at 16:06 +0200, Jules Colding wrote:
> Hi,
> 
> On Fri, 2007-06-22 at 14:18 +0200, Jules Colding wrote:
> > > 	-really- it would be way better to instrument your glib and find out
> > > why the timeout thing is not getting called. -One- possibility may be
> > > that you're not setting it to be a 'recursive' source (although perhaps
> > > unlikely given the lack of re-enterancy there).
> > 
> > I think that I need to crawl down into glib and take a look... 
> 
> Sigh... I've been crawling all over the glib source. I can see that my
> timeout source is being added to the context(s) but nothing happens.
> 
> I've tried the main context and the giop loop context but with equally
> disappointing results.
> 
> Any advise/help/encouraging yells would be highly appreciated.

  Try using strace to run your test program.  Make sure the the Link
socket is always in non-blocking mode; if it is in blocking mode, for
sure glib timeouts will not work.

-- 
Gustavo J. A. M. Carneiro
INESC Porto, Telecommunications and Multimedia Unit
"The universe is always one step beyond logic." -- Frank Herbert

From michael.meeks@novell.com  Fri Jun 22 11:55:20 2007
Return-Path: 
X-Original-To: orbit-list@gnome.org
Delivered-To: orbit-list@gnome.org
Received: from localhost (localhost.localdomain [127.0.0.1])
	by menubar.gnome.org (Postfix) with ESMTP id 413983B0320
	for ; Fri, 22 Jun 2007 11:55:20 -0400 (EDT)
X-Virus-Scanned: by amavisd-new at gnome.org
X-Spam-Score: -2.207
X-Spam-Level: 
X-Spam-Status: No, score=-2.207 tagged_above=-999 required=2
	tests=[AWL=-0.221, BAYES_00=-2.599, DATE_IN_PAST_03_06=0.478,
	FORGED_RCVD_HELO=0.135]
X-Amavis-OS-Fingerprint: Linux 2.6, seldom 2.4 (older, 4) (up: 313 hrs),
	(distance 17, link: ethernet/modem), [195.135.221.2]
Received: from menubar.gnome.org ([127.0.0.1])
	by localhost (menubar.gnome.org [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id 90woONc-HkGl for ;
	Fri, 22 Jun 2007 11:55:18 -0400 (EDT)
Received: from emea5-mh.id5.novell.com (charybdis-ext.suse.de [195.135.221.2])
	by menubar.gnome.org (Postfix) with ESMTP id B12693B02EE
	for ; Fri, 22 Jun 2007 11:55:17 -0400 (EDT)
Received: from [192.168.0.8] ([149.44.162.75])
	by emea5-mh.id5.novell.com with ESMTP (TLS encrypted);
	Fri, 22 Jun 2007 17:55:08 +0200
Subject: Re: New GIOP timeout patch - please review
From: Michael Meeks 
To: Jules Colding 
In-Reply-To: <1182514728.25157.55.camel@omc-2.omesc.com>
References: <1182426688.5074.176.camel@omc-2.omesc.com>
	<1182430181.5074.190.camel@omc-2.omesc.com>
	<1182426383.3917.96.camel@localhost>
	<1182514728.25157.55.camel@omc-2.omesc.com>
Content-Type: multipart/mixed; boundary="=-QEPxrqlJAOfl+9eoveNq"
Organization: Novell, Inc.
Date: Fri, 22 Jun 2007 13:31:23 +0100
Message-Id: <1182515483.3917.225.camel@localhost>
Mime-Version: 1.0
X-Mailer: Evolution 2.6.0 
Cc: ORBit2 ,
	"Gustavo J. A. M.  Carneiro" 
X-BeenThere: orbit-list@gnome.org
X-Mailman-Version: 2.1.8
Precedence: list
Reply-To: michael.meeks@novell.com
List-Id: ORBit CORBA implementation use & development 
List-Unsubscribe: ,
	
List-Archive: 
List-Post: 
List-Help: 
List-Subscribe: ,
	
X-List-Received-Date: Fri, 22 Jun 2007 15:55:20 -0000


--=-QEPxrqlJAOfl+9eoveNq
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Hi Jules,

On Fri, 2007-06-22 at 14:18 +0200, Jules Colding wrote:
> I think that I need to crawl down into glib and take a look... My
> current test patch is below as well as my modifications to the echo
> client/server. The echo server must be executed as:

	;-) we're attaching to the wrong main context:

/echo-client --GIOPTimeoutMSEC=30 `cat /tmp/ior` 1
** Message: 0
Adding timeout for 30 milliseconds
Timeout function invoked
** Message: 00
** Message: 1
Printing exception : IDL:omg.org/CORBA/TIMEOUT:1.0
** Message: 2
** Message: 3
** Message: A
** Message: B
** Message: C
** Message: C

	I attach a patch that works for me [ I was missing timeout.h FWIW ]...

	Things to fix:

	* lifecycle, we can't just add timeouts without removing them
	  again if our connection is closed.

	* adding a timeout is quite expensive CPU-wise; we might do 
	  better by simply extending linc-source.c (link_source_prepare)
	  to handle the timeouts & manage how long each connection has
	  been waiting itself: to avoid adding many more sources. 
	  [ though not sure how to get notified of that timeout - check
	  the glib/gmain.c source I guess ].

	HTH,

		Michael.

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


--=-QEPxrqlJAOfl+9eoveNq
Content-Disposition: attachment; filename=for-jules.diff
Content-Type: text/x-patch; name=for-jules.diff; charset=us-ascii
Content-Transfer-Encoding: 7bit


--=-QEPxrqlJAOfl+9eoveNq--

From colding@omesc.com  Mon Jun 25 08:54:21 2007
Return-Path: 
X-Original-To: orbit-list@gnome.org
Delivered-To: orbit-list@gnome.org
Received: from localhost (localhost.localdomain [127.0.0.1])
	by menubar.gnome.org (Postfix) with ESMTP id EA38F3B0215
	for ; Mon, 25 Jun 2007 08:54:20 -0400 (EDT)
X-Virus-Scanned: by amavisd-new at gnome.org
X-Spam-Score: -3.522
X-Spam-Level: 
X-Spam-Status: No, score=-3.522 tagged_above=-999 required=2
	tests=[BAYES_00=-2.599, L_P0F_Unix=-1, TW_CN=0.077]
X-Amavis-OS-Fingerprint: FreeBSD 6.x (1) (up: 6213 hrs), (distance 25, link:
	ethernet/modem), [85.218.129.6]
Received: from menubar.gnome.org ([127.0.0.1])
	by localhost (menubar.gnome.org [127.0.0.1]) (amavisd-new, port 10024)
	with ESMTP id MvBaPlafxspC for ;
	Mon, 25 Jun 2007 08:54:15 -0400 (EDT)
Received: from mail-smtp3.ode.cdnet.dk (mail-smtp3.ode.cdnet.dk [85.218.129.6])
	by menubar.gnome.org (Postfix) with ESMTP id BD26E3B0150
	for ; Mon, 25 Jun 2007 08:54:14 -0400 (EDT)
Received: from localhost (localhost [127.0.0.1])
	by mail-smtp3.ode.cdnet.dk (Postfix) with ESMTP id 4F74722802B;
	Mon, 25 Jun 2007 14:54:12 +0200 (CEST)
X-Virus-Scanned: amavisd-new at cdnet.dk
Received: from mail-smtp3.ode.cdnet.dk ([127.0.0.1])
	by localhost (mail-smtp3.ode.cdnet.dk [127.0.0.1]) (amavisd-new,
	port 10024)
	with ESMTP id BEuaUnavTLD0; Mon, 25 Jun 2007 14:54:08 +0200 (CEST)
Received: from [192.168.0.2] (unknown [85.218.191.254])
	by mail-smtp3.ode.cdnet.dk (Postfix) with ESMTP id 9A57B228029;
	Mon, 25 Jun 2007 14:54:08 +0200 (CEST)
Subject: Re: New GIOP timeout patch - please review
From: Jules Colding 
To: michael.meeks@novell.com
In-Reply-To: <1182515483.3917.225.camel@localhost>
References: <1182426688.5074.176.camel@omc-2.omesc.com>
	<1182430181.5074.190.camel@omc-2.omesc.com>
	<1182426383.3917.96.camel@localhost>
	<1182514728.25157.55.camel@omc-2.omesc.com>
	<1182515483.3917.225.camel@localhost>
Content-Type: text/plain
Date: Mon, 25 Jun 2007 14:54:08 +0200
Message-Id: <1182776048.28397.33.camel@omc-2.omesc.com>
Mime-Version: 1.0
X-Mailer: Evolution 2.8.3 
Content-Transfer-Encoding: 7bit
Cc: ORBit2 ,
	"Gustavo J. A. M.  Carneiro" 
X-BeenThere: orbit-list@gnome.org
X-Mailman-Version: 2.1.8
Precedence: list
List-Id: ORBit CORBA implementation use & development 
List-Unsubscribe: ,
	
List-Archive: 
List-Post: 
List-Help: 
List-Subscribe: ,
	
X-List-Received-Date: Mon, 25 Jun 2007 12:54:21 -0000

On Fri, 2007-06-22 at 13:31 +0100, Michael Meeks wrote:
> Hi Jules,
> 
> On Fri, 2007-06-22 at 14:18 +0200, Jules Colding wrote:
> > I think that I need to crawl down into glib and take a look... My
> > current test patch is below as well as my modifications to the echo
> > client/server. The echo server must be executed as:
> 
> 	;-) we're attaching to the wrong main context:

OK -that would explain everything ;-) Thanks a lot for spotting that.


> 	I attach a patch that works for me [ I was missing timeout.h FWIW ]...
> 
> 	Things to fix:
> 
> 	* lifecycle, we can't just add timeouts without removing them
> 	  again if our connection is closed.

This is fixed in my new patch below.


> 	* adding a timeout is quite expensive CPU-wise; we might do 
> 	  better by simply extending linc-source.c (link_source_prepare)
> 	  to handle the timeouts & manage how long each connection has
> 	  been waiting itself: to avoid adding many more sources. 
> 	  [ though not sure how to get notified of that timeout - check
> 	  the glib/gmain.c source I guess ].

Hmm... I like to wait a bit with this one. I think that my current
fumbling around has lasted long enough and that we need to get the
correted timeout approach into mainline asap. The above can always be
attended to later.

The new patch is below. Please ignore the changes to the echo
client/server. They will be reverted before the patch is committed. 

Comments?

Best regards,
  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 
 #include 
 #include 
+#include 
+#include 
 
 #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,110 @@
 	return TRUE;
 }
 
+struct timeout_thread_data {
+	GIOPThread *tdata;
+	LinkConnection *lcnx;
+};
+
+/* static gpointer */
+/* giop_timeout(gpointer data) */
+/* { */
+/* 	LinkConnection *lcnx = ((struct timeout_thread_data*)data)->lcnx; */
+/* 	GIOPThread *tdata =  ((struct timeout_thread_data*)data)->tdata; */
+/* 	struct timespec tv; */
+
+/* 	g_assert (lcnx->timeout_mutex); */
+
+/* 	tv.tv_sec = lcnx->timeout_msec / 1000; */
+/* 	tv.tv_nsec = (lcnx->timeout_msec - tv.tv_sec*1000) * 1000000; */
+	
+/* 	nanosleep (&tv, NULL); */
+
+/* 	g_mutex_lock (lcnx->timeout_mutex); */
+/* 	if (lcnx->timeout_status == LINK_TIMEOUT_UNKNOWN) */
+/* 		lcnx->timeout_status = LINK_TIMEOUT_YES; */
+/* 	else { */
+/* 		g_mutex_unlock (lcnx->timeout_mutex); */
+/* 		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 NULL; */
+/* } */
+
+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 +1475,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 
 
 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 : "",
@@ -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  
+
+	* 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  
+
+	* 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  
Index: test/echo-server.c
===================================================================
--- test/echo-server.c	(revision 2003)
+++ test/echo-server.c	(working copy)
@@ -40,7 +40,8 @@
 	signal(SIGTERM, exit);
 
 	CORBA_exception_init(&ev);
-	orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
+//	orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
+	orb = CORBA_ORB_init(&argc, argv, "orbit-io-thread", &ev);
 	g_assert(ev._major == CORBA_NO_EXCEPTION);
 
 	echo_srv_start_poa(orb, &ev);
Index: test/echo-srv.c
===================================================================
--- test/echo-srv.c	(revision 2003)
+++ test/echo-srv.c	(working copy)
@@ -22,8 +22,10 @@
 #include 
 #include 
 #include 
+#include 
 #include "echo.h"
 #include "echo-share.h"
+#include "timeout.h"
 
 /**
    This is used by echo-server.c and echo-local.c
@@ -47,7 +49,9 @@
 		g_message ("[server] %s", astring);
 
 	*outnum = rand() % 100;
-	
+
+	sleep(SLEEP);
+
 	return CORBA_Object_duplicate (the_echo_client, ev);
 }
 
Index: test/echo-client.c
===================================================================
--- test/echo-client.c	(revision 2003)
+++ test/echo-client.c	(working copy)
@@ -21,15 +21,24 @@
 #include 
 
 #include "echo.h"
+#include "timeout.h"
 
 
 #define ABORT_IF_EXCEPTION(_ev, _message)                    \
-if ((_ev)->_major != CORBA_NO_EXCEPTION) {                   \
-  g_error("%s: %s", _message, CORBA_exception_id (_ev));     \
+	if ((_ev) && (_ev)->_major != CORBA_NO_EXCEPTION) {	       \
+  g_error("%s: %s\n", _message, CORBA_exception_id (_ev));     \
   CORBA_exception_free (_ev);                                \
   abort();                                                   \
 }
 
+#define PRINT_EXCEPTION(_ev, _message) do { \
+		if (_ev) \
+			g_print("%s: %s\n", _message, CORBA_exception_id (_ev)); \
+		else \
+			g_print("No exception\n"); \
+	} while (0); 
+
+
 static Echo echo_client, bec;
 
 static gboolean echo_opt_quiet = FALSE;
@@ -45,7 +54,8 @@
 	int niters = 1000;
 
 	CORBA_exception_init(&ev);
-	orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
+//	orb = CORBA_ORB_init(&argc, argv, "orbit-local-orb", &ev);
+	orb = CORBA_ORB_init(&argc, argv, "orbit-io-thread", &ev);
 
 	/* read IOR from command line as first argument */
 	if(argc < 2) {
@@ -73,32 +83,51 @@
 	for(i = 0; i < niters; i++) {
 		/* Method call without any argument, usefull to tell
 		 * lifeness */
-		Echo_doNothing(echo_client, &ev);
-		ABORT_IF_EXCEPTION (&ev, "service raised exception ");
+/* 		Echo_doNothing(echo_client, &ev); */
+/* 		ABORT_IF_EXCEPTION (&ev, "service raised exception "); */
 
 		/* Ask echo-service to print string 'buf' on console. The
 		 * service returns random double float value in 'vr' */
-		g_snprintf(buf, sizeof(buf), "Hello, world [%d]", i);
+/* 		g_snprintf(buf, sizeof(buf), "Hello, world [%d]", i); */
+/* 		bec = Echo_echoString(echo_client, buf, &rv, &ev); */
+/* 		ABORT_IF_EXCEPTION (&ev, "service raised exception "); */
+
+		/* Test the GIOP timeout functionality. The server must be started 
+		 * with "--GIOPTimeoutLimit=2000 --ORBIIOPIPv4=1" for this test to work. */
+		g_snprintf(buf, sizeof(buf), TIMEOUT_STR);
+		g_message("0");
 		bec = Echo_echoString(echo_client, buf, &rv, &ev);
-		ABORT_IF_EXCEPTION (&ev, "service raised exception ");
+		g_message("00");
+		if (ev._major != CORBA_NO_EXCEPTION) {
+			g_message("1");
+			PRINT_EXCEPTION (&ev, "Printing exception ");
+			g_message("2");
+			bec = CORBA_OBJECT_NIL;
+			g_message("3");
+		}
+		CORBA_exception_init(&ev);
+		g_message("A");
 
 		/* print random value generated by echo-service */
-		if ( !echo_opt_quiet )
-			g_message("[client] %g", rv);
+/* 		if ( !echo_opt_quiet ) */
+/* 			g_message("[client] %g", rv); */
 
 		/* Asynchronous/oneway method call, the function returns
 		 * immediately.  Usefull for log-message transfer */
-		Echo_doOneWay(echo_client, "log message ", &ev);
-		ABORT_IF_EXCEPTION (&ev, "service raised exception ");
+/* 		Echo_doOneWay(echo_client, "log message ", &ev); */
+/* 		ABORT_IF_EXCEPTION (&ev, "service raised exception "); */
 
 		/* release first object reference and use the new one for
 		 * next loop */
 		CORBA_Object_release(echo_client, &ev);
+		g_message("B");
 		ABORT_IF_EXCEPTION (&ev, "service raised exception ");
+		g_message("C");
 
 		/* swap object references */ 
 		echo_client = bec; bec = CORBA_OBJECT_NIL;
 	}
+	g_message("C");
     
 	/* release initial object reference */
 	CORBA_Object_release(echo_client, &ev);
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