Tony -<br><br>Thanks, that really helps.<br><br>- Jim<br><br>Jim Irrer     <a href="mailto:irrer@umich.edu">irrer@umich.edu</a>       (734) 647-4409<br>University of Michigan Hospital Radiation Oncology<br>519 W. William St.             Ann Arbor, MI 48103<br>

<br><br><div class="gmail_quote">---------- Forwarded message ----------<br>From: <b class="gmail_sendername">Tony Garnock-Jones</b> <span dir="ltr">&lt;<a href="mailto:tonyg@lshift.net">tonyg@lshift.net</a>&gt;</span><br>
Date: Thu, Jul 1, 2010 at 8:39 PM<br>Subject: Re: C client and thread safety<br>To: Jim Irrer &lt;<a href="mailto:irrer@umich.edu">irrer@umich.edu</a>&gt;<br>Cc: rabbitmq-discuss &lt;<a href="mailto:rabbitmq-discuss@lists.rabbitmq.com">rabbitmq-discuss@lists.rabbitmq.com</a>&gt;<br>
<br><br>Hi Jim,<br>
<div class="im"><br>
Jim Irrer wrote:<br>
&gt; I&#39;m working with the RabbitMQ C client, and had a few questions<br>
&gt; about thread safety.<br>
<br>
</div>In general, there is no thread awareness built in to librabbitmq at all. It is<br>
currently the responsibility of applications using the library to ensure that<br>
multiple threads don&#39;t screw up the library&#39;s state.<br>
<br>
That said, there is no longer any global state at all in the library, so if you<br>
stick to one connection (and thus one socket) per thread, you should be fine.<br>
<div class="im"><br>
&gt; Must a socket returned by amqp_open_socket be exclusively<br>
&gt; associated with one connection, or can it be used for multiple<br>
&gt; connections?<br>
<br>
</div>One connection. Each AMQP connection needs exactly one socket to communicate over.<br>
<div class="im"><br>
&gt; Must a socket returned by amqp_open_socket be exclusively<br>
&gt; used by one thread, or can it be used by multiple threads?<br>
<br>
</div>The connection associated with the socket must be used by one thread *at a<br>
time*. The locking can get quite complicated when you take into account the way<br>
librabbitmq currently deals with incoming events, so sticking with one<br>
connection for each thread makes life much easier.<br>
<div class="im"><br>
&gt; Must a connection returned by amqp_new_connection be exclusively<br>
&gt; used to read from or write to one channel/queue, or is using multiple ok,<br>
&gt; even in a multi-threaded environment.<br>
<br>
</div>Multiple are OK, but again, each connection is best kept to a single thread.<br>
Think of multiple channels as separate *transaction* and *error reporting*<br>
contexts; they don&#39;t buy much else in current versions of the AMQP protocol :-)<br>
<div class="im"><br>
&gt; If any of these can be used by multiple threads, is there a performance<br>
&gt; advantage in reusing the same socket or connection, or is using multiple<br>
&gt; ones better?<br>
<br>
</div>Using a single connection with multiple channels means that TCPs<br>
congestion-avoidance counts all AMQP traffic as a single stream, whereas using<br>
multiple connections with a single channel each means that TCP will count each<br>
stream separately. Which is more appropriate to your application depends on the<br>
structure of your network: the former might be more appropriate for a WAN link,<br>
the latter for a LAN or a datacentre, etc.<br>
<div class="im"><br>
&gt; It looks like channels (created with amqp_channel_open) are identified<br>
&gt; by (small?)<br>
&gt; integers chosen by the application and are associated with the<br>
&gt; connection.  This<br>
&gt; means that it is the responsibility of the application to choose unique<br>
&gt; numbers,<br>
&gt; properly close them, etc..   It would seem cleaner to pass a connection as a<br>
&gt; single parameter to amqp_channel_open and have it return a pointer to a<br>
&gt; channel,<br>
&gt; and the list of channels would be maintained in the connection.<br>
<br>
</div>Yes, there is a lot of per-channel state management the library currently<br>
doesn&#39;t do. A set of &quot;active&quot; channel numbers might not be too hard to manage.<br>
<div class="im"><br>
&gt; Also, it looks like amqp_new_connection uses &#39;calloc&#39; to allocate<br>
&gt; memory for a connection, but amqp_connection_close does not do<br>
&gt; a &#39;free&#39; to avoid the memory leak.  Maybe that was intentional, but if<br>
&gt; not it should be changed.<br>
<br>
</div>The amqp_connection_close() function causes an AMQP Connection.Close RPC to<br>
happen on the open socket, but does not then tear down any of the application<br>
state: that&#39;s what amqp_destroy_connection() is for. The relevant pairings are<br>
roughly<br>
<br>
For local connection state management (calloc/free):<br>
  amqp_new_connection<br>
  amqp_destroy_connection<br>
<br>
For remote connection state management (Connection.Open/Tune/Close, once local<br>
connection state exists):<br>
  amqp_login<br>
  amqp_connection_close<br>
...plus interactions required on receipt of a Connection.Close method frame<br>
from the peer.<br>
<br>
Cheers,<br>
<font color="#888888">  Tony<br>
<br>
</font></div><br>