<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Techie Blog</title>
	<atom:link href="http://golubenco.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://golubenco.org</link>
	<description>A technical post, every once in a while</description>
	<lastBuildDate>Sat, 08 Oct 2011 10:42:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Understanding the code inside Tornado, the asynchronous web server</title>
		<link>http://golubenco.org/2009/09/19/understanding-the-code-inside-tornado-the-asynchronous-web-server-powering-friendfeed/</link>
		<comments>http://golubenco.org/2009/09/19/understanding-the-code-inside-tornado-the-asynchronous-web-server-powering-friendfeed/#comments</comments>
		<pubDate>Sat, 19 Sep 2009 21:17:11 +0000</pubDate>
		<dc:creator>tsg</dc:creator>
				<category><![CDATA[Code hicking]]></category>
		<category><![CDATA[async]]></category>
		<category><![CDATA[codehike]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tornado]]></category>
		<category><![CDATA[tornadoweb]]></category>
		<category><![CDATA[webserver]]></category>

		<guid isPermaLink="false">http://golubenco.org/?p=16</guid>
		<description><![CDATA[My goal here is to have a walk through the lower layers of the Tornado asynchronous web server. I take a bottom-up approach, starting with the polling loop and going up to the application layer, pointing out the interesting things I see on my way. So if you plan on reading the source code of [...]]]></description>
			<content:encoded><![CDATA[<p>My goal here is to have a walk through the lower layers of the Tornado 
asynchronous web server. I take a bottom-up approach, starting with the
polling loop and going up to the application layer, pointing out the interesting
things I see on my way.</p>

<p>So if you plan on reading the source code of the Tornado web 
framework, or you are just curious to see how an asynchronous web server works, I 
would love to be your guide.</p>

<p>After reading this, you will:</p>

<ul>
<li>be able to write the server part of <a href="http://en.wikipedia.org/wiki/Comet_%28programming%29">Comet</a> applications, even if you have 
to do it from scratch</li>
<li>have a better understanding of the Tornado web framework, if you plan do develop 
on it</li>
<li>have a bit more informed opinion in the <a href="http://searchyc.com/submissions/tornado+twisted">tornado-twisted debate</a></li>
</ul>

<h2>Intro</h2>

<p>I&#8217;ll start with a few words of introduction to the Tornado 
project, in case you  have no idea what it is and why you might be interested in it. 
If you&#8217;re already interested in it, just jump to the next section.</p>

<p><a href="http://tornadoweb.org">Tornado</a> is a asynchronous http server and web 
framework written in Python. It is the framework that powers the <a href="http://friendfeed.com">FriendFeed</a> website, recently acquired by Facebook. FriendFeed has quite 
<a href="http://siteanalytics.compete.com/friendfeed.com/">a few users</a> and many 
real-time features, so performance and scalability must have high priorities there. 
Since it is open source now (kudos to Facebook), we can all have a look inside it
to see how it works.</p>

<p>I also feel obliged to talk a bit on <strong>nonblocking IO</strong> or <strong>asynchronous IO</strong> (AIO) . 
If you already know what it is, <code>goto next_section</code>. I&#8217;ll try to demonstrate it 
with a simple example.</p>

<p>Let&#8217;s suppose you&#8217;re writing an application that has to query another server 
for some data (the database for example, or some sort of remote API) and it&#8217;s 
known that this query can take a long time. Let&#8217;s say, 5 seconds.
In many web frameworks the handler would look something like:</p>

<pre class="lang-python"><code><span class="kw1">def</span> handler_request<span class="br0">&#40;</span><span class="kw2">self</span>, request<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; answ = <span class="kw2">self</span>.<span class="me1">remote_server</span>.<span class="me1">query</span><span class="br0">&#40;</span>request<span class="br0">&#41;</span> <span class="co1"># this takes 5 seconds</span><br />
&nbsp; &nbsp; request.<span class="me1">write_response</span><span class="br0">&#40;</span>answ<span class="br0">&#41;</span></code></pre>

<p>If you do this in a single thread, you will serve one client every 5 second. During
the five secs, all other have to wait, so you&#8217;re serving clients with a whooping 
rate of 0.2 requests per second. Awesome!</p>

<p>Of course, nobody is that naive, so most will use a multi-threaded server to be able
to support more clients at once. Lets say you have 20 threads. 
You improved performance 20 times, so the rate is now 4 request per 
second. Still, way too small.
You can keep throwing threads at the problem, but threads are expensive in terms of
 memory usage and scheduling.
I doubt you&#8217;ll ever reach hundreds of requests per second this way.</p>

<p>With AIO, however, <strong>thousands of such requests per second are a breeze</strong>. The handler 
has to be changed to look something like this:</p>

<pre class="lang-python"><code><span class="kw1">def</span> handler_request<span class="br0">&#40;</span><span class="kw2">self</span>, request<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">remote_server</span>.<span class="me1">query_async</span><span class="br0">&#40;</span>request, <span class="kw2">self</span>.<span class="me1">response_received</span><span class="br0">&#41;</span> &nbsp; &nbsp; <br />
<br />
<span class="kw1">def</span> response_received<span class="br0">&#40;</span><span class="kw2">self</span>, request, answ<span class="br0">&#41;</span>: &nbsp; &nbsp;<span class="co1"># this is called 5 seconds later</span><br />
&nbsp; &nbsp; request.<span class="me1">write</span><span class="br0">&#40;</span>answ<span class="br0">&#41;</span></code></pre>

<p>The idea is that we&#8217;re not blocking while waiting for the answer to come. Instead,
we give the framework a callback function to call us when the answer has come.
 In the mean time, we&#8217;re free to serve other clients.</p>

<p>This is also the downside of AIO: the code will be a bit&#8230; well, <em>twisted</em>. Also, if 
you&#8217;re in a single threaded AIO server like Tornado, you have to be careful never
to block, because all the pending requests will be delayed by that.</p>

<p>A great resource to learn more (than this over simplistic intro) about asynchronous IO
 is <a href="http://www.kegel.com/c10k.html">The C10K problem</a> page.</p>

<h2>Source code</h2>

<p>The project is hosted at <a href="http://github.com/facebook/tornado">github</a>. 
You can get it, although you don&#8217;t need it for reading this article, with:</p>

<pre><code>git clone git://github.com/facebook/tornado.git
</code></pre>

<p>The <code>tornado</code> subdirectory contains a <code>.py</code> file for each of the modules so you 
can easily identify them if you have a checkout of the repository. 
In each source file, you will find at least one large doc string explaining the module, 
and giving an example or two on how to use it.</p>

<h2>IOLoop</h2>

<p>Lets go directly into the core of the server and look at the 
<a href="http://github.com/facebook/tornado/blob/master/tornado/ioloop.py#L17">ioloop.py file</a>.
This module is the heart of the asynchronous mechanism. It keeps a list of the
 open file descriptors and handlers for each. Its job is to select the ones that are
ready for reading or writing and call the associated handler.</p>

<p>To add a socket to the <code>IOLoop</code>, the application calls the <code>add_handler()</code> method:</p>

<pre class="lang-python"><code><span class="kw1">def</span> add_handler<span class="br0">&#40;</span><span class="kw2">self</span>, fd, handler, events<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;&quot;Registers the given handler to receive the given events for fd.&quot;&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>._handlers<span class="br0">&#91;</span>fd<span class="br0">&#93;</span> = handler<br />
&nbsp; &nbsp; <span class="kw2">self</span>._impl.<span class="me1">register</span><span class="br0">&#40;</span>fd, events | <span class="kw2">self</span>.<span class="me1">ERROR</span><span class="br0">&#41;</span></code></pre>

<p>The <code>_handlers</code> dictionary maps the file descriptor with the function  to be called 
when the file descriptor is ready (handler in Tornado terminology).
Then, the descriptor is registered to the epoll list. Tornado cares about three 
types of events: <code>READ</code>, <code>WRITE</code> and <code>ERROR</code>. As you can see, <code>ERROR</code> is automatically 
added in for you.</p>

<p>The <code>self._impl</code> is an alias to either <a href="http://docs.python.org/library/select.html#select.epoll">select.epoll()</a> or <a href="http://docs.python.org/library/select.html#select.select">select.select()</a>. We&#8217;ll see how it chooses between them a bit later.</p>

<p>Now lets see the actual main loop, somehow weirdly placed in the <code>start()</code> method:</p>

<pre class="lang-python"><code><span class="kw1">def</span> start<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;&quot;Starts the I/O loop.<br />
<br />
&nbsp; &nbsp; The loop will run until one of the I/O handlers calls stop(), which<br />
&nbsp; &nbsp; will make the loop stop after the current event iteration completes.<br />
&nbsp; &nbsp; &quot;&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>._running = <span class="kw2">True</span><br />
&nbsp; &nbsp; <span class="kw1">while</span> <span class="kw2">True</span>:<br />
<br />
&nbsp; &nbsp; <span class="br0">&#91;</span> ... <span class="br0">&#93;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw1">not</span> <span class="kw2">self</span>._running:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#91;</span> ... <span class="br0">&#93;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; event_pairs = <span class="kw2">self</span>._impl.<span class="me1">poll</span><span class="br0">&#40;</span>poll_timeout<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">except</span> <span class="kw2">Exception</span>, e:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> e.<span class="me1">args</span> == <span class="br0">&#40;</span><span class="nu0">4</span>, <span class="st0">&quot;Interrupted system call&quot;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">logging</span>.<span class="me1">warning</span><span class="br0">&#40;</span><span class="st0">&quot;Interrupted system call&quot;</span>, exc_info=<span class="nu0">1</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">continue</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">raise</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># Pop one fd at a time from the set of pending fds and run</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># its handler. Since that handler may perform actions on</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># other file descriptors, there may be reentrant calls to</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># this IOLoop that update self._events</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._events.<span class="me1">update</span><span class="br0">&#40;</span>event_pairs<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> <span class="kw2">self</span>._events:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fd, events = <span class="kw2">self</span>._events.<span class="me1">popitem</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._handlers<span class="br0">&#91;</span>fd<span class="br0">&#93;</span><span class="br0">&#40;</span>fd, events<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">except</span> <span class="kw2">KeyboardInterrupt</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">raise</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">except</span> <span class="kw2">OSError</span>, e:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> e<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> == <span class="kw3">errno</span>.<span class="me1">EPIPE</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># Happens when the client closes the connection</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">pass</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">logging</span>.<span class="me1">error</span><span class="br0">&#40;</span><span class="st0">&quot;Exception in I/O handler for fd %d&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fd, exc_info=<span class="kw2">True</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">except</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">logging</span>.<span class="me1">error</span><span class="br0">&#40;</span><span class="st0">&quot;Exception in I/O handler for fd %d&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fd, exc_info=<span class="kw2">True</span><span class="br0">&#41;</span></code></pre>

<p>The <code>poll()</code> function returns a dictionary with <code>(fd: events)</code> pairs, stored 
in the <code>event_pairs</code> variable. The <code>"Interrupted system call"</code> special case 
exception is needed 
because the C library <code>poll()</code> function can return <code>EINTR</code> (which has the numerical 
value of 4), when a signal comes before any events occurred. 
See <a href="http://www.cl.cam.ac.uk/cgi-bin/manpage?2+poll">man poll</a> for details.</p>

<p>The inner while loop takes the pairs from the <code>event_pairs</code> dictionary one by one 
and calls the associated handler. The pipe error exception is silenced here. To keep
the generality of this class it would have been perhaps a better idea to catch this 
in the http handlers, but it was probably easier like this.</p>

<p>The comment explains why the dictionary had to be parsed using <code>popitem()</code> rather than
the more obvious:</p>

<pre class="lang-python"><code><span class="kw1">for</span> fd, events <span class="kw1">in</span> <span class="kw2">self</span>._events.<span class="me1">items</span><span class="br0">&#40;</span><span class="br0">&#41;</span>:</code></pre>

<p>In a nutshell, the dictionary can be modified 
during the loop, inside the handlers. See, for example, the <code>removeHandler()</code> function.
The method extracts the fd from the <code>_events</code> dictionary, so that the handler is not 
called even if it was selected by the current poll iteration.</p>

<pre class="lang-python"><code><span class="kw1">def</span> remove_handler<span class="br0">&#40;</span><span class="kw2">self</span>, fd<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;&quot;Stop listening for events on fd.&quot;&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>._handlers.<span class="me1">pop</span><span class="br0">&#40;</span>fd, <span class="kw2">None</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>._events.<span class="me1">pop</span><span class="br0">&#40;</span>fd, <span class="kw2">None</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._impl.<span class="me1">unregister</span><span class="br0">&#40;</span>fd<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">except</span> <span class="kw2">OSError</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">logging</span>.<span class="me1">debug</span><span class="br0">&#40;</span><span class="st0">&quot;Error deleting fd from IOLoop&quot;</span>, exc_info=<span class="kw2">True</span><span class="br0">&#41;</span></code></pre>

<h2>The (pointless) loop termination trick</h2>

<p>A nice trick is how the loop is stopped. The <code>self._running</code> variable is used to break from it
and it can be set to <code>False</code> from the handlers by using the <code>stop()</code> method. 
Normally, that would just be the end of it, but
the <code>stop()</code> method might be also called from a signal handler. If 1) the loop is in
<code>poll()</code>, 2) no requests are coming to the server and 3) the signal is not delivered to
the right thread by the OS, you would have to wait for the poll to 
timeout. Considering how unlikely this is and that <code>poll_timeout</code> is 0.2 seconds by default, 
that&#8217;s hardly a tragedy, really.</p>

<p>But anyway, to do it they use an anonymous pipe with one end in the set of polled file descriptors. When terminating, 
it writes something on the other end, effectively waking up the loop from poll.
Here is the selected code for it:</p>

<pre class="lang-python"><code><span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, impl=<span class="kw2">None</span><span class="br0">&#41;</span>:<br />
<br />
&nbsp; &nbsp; <span class="br0">&#91;</span>...<span class="br0">&#93;</span><br />
<br />
&nbsp; &nbsp; <span class="co1"># Create a pipe that we send bogus data to when we want to wake</span><br />
&nbsp; &nbsp; <span class="co1"># the I/O loop when it is idle</span><br />
&nbsp; &nbsp; r, w = <span class="kw3">os</span>.<span class="me1">pipe</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>._set_nonblocking<span class="br0">&#40;</span>r<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>._set_nonblocking<span class="br0">&#40;</span>w<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>._waker_reader = <span class="kw3">os</span>.<span class="me1">fdopen</span><span class="br0">&#40;</span>r, <span class="st0">&quot;r&quot;</span>, <span class="nu0">0</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>._waker_writer = <span class="kw3">os</span>.<span class="me1">fdopen</span><span class="br0">&#40;</span>w, <span class="st0">&quot;w&quot;</span>, <span class="nu0">0</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">add_handler</span><span class="br0">&#40;</span>r, <span class="kw2">self</span>._read_waker, <span class="kw2">self</span>.<span class="me1">WRITE</span><span class="br0">&#41;</span><br />
<br />
<br />
<span class="kw1">def</span> _wake<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._waker_writer.<span class="me1">write</span><span class="br0">&#40;</span><span class="st0">&quot;x&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">except</span> <span class="kw2">IOError</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">pass</span></code></pre>

<p>In fact, it seems to be a bug in the above code: the read file descriptor <code>r</code>, although
opened for reading, is registered with the <code>WRITE</code> event, which cannot occur.  As I said 
earlier, it hardly makes a difference so I&#8217;m
not surprised that they actually didn&#8217;t noticed this is not working.
I&#8217;ve pinged
the 
<a href="http://groups.google.com/group/python-tornado/browse_thread/thread/eb3d9a85ed6b71a0/0288ac7bc61b4cf0">mailing list</a> 
about this, but I got no answer so far.</p>

<h2>Timers</h2>

<p>Another nice feature of the <code>IOLoop</code> module is the simple timers implementation. A list of 
timers is maintained sorted by expiration time, by using python&#8217;s <a href="http://docs.python.org/library/bisect.html">bisect</a>
module:</p>

<pre class="lang-python"><code><span class="kw1">def</span> add_timeout<span class="br0">&#40;</span><span class="kw2">self</span>, deadline, callback<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;&quot;Calls the given callback at the time deadline from the I/O loop.&quot;&quot;&quot;</span><br />
&nbsp; &nbsp; timeout = _Timeout<span class="br0">&#40;</span>deadline, callback<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw3">bisect</span>.<span class="me1">insort</span><span class="br0">&#40;</span><span class="kw2">self</span>._timeouts, timeout<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> timeout</code></pre>

<p>Inside the main loop, the callbacks from all the expired timers are simply 
executed in that order, until the current time is reached. The poll timeout is
adjusted such as the next timer is not delayed if no new requests arrive.</p>

<pre class="lang-python"><code><span class="kw2">self</span>._running = <span class="kw2">True</span><br />
<span class="kw1">while</span> <span class="kw2">True</span>:<br />
&nbsp; &nbsp; poll_timeout = <span class="nu0">0.2</span><br />
<br />
&nbsp; &nbsp; <span class="br0">&#91;</span> ... <span class="br0">&#93;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">self</span>._timeouts:<br />
&nbsp; &nbsp; &nbsp; &nbsp; now = <span class="kw3">time</span>.<span class="kw3">time</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">while</span> <span class="kw2">self</span>._timeouts <span class="kw1">and</span> <span class="kw2">self</span>._timeouts<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.<span class="me1">deadline</span> <span class="sy0">&lt;</span>= now:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; timeout = <span class="kw2">self</span>._timeouts.<span class="me1">pop</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._run_callback<span class="br0">&#40;</span>timeout.<span class="me1">callback</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">self</span>._timeouts:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; milliseconds = <span class="kw2">self</span>._timeouts<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.<span class="me1">deadline</span> - now<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; poll_timeout = <span class="kw2">min</span><span class="br0">&#40;</span>milliseconds, poll_timeout<span class="br0">&#41;</span><br />
<br />
<span class="br0">&#91;</span> ... <span class="me1">poll</span> <span class="br0">&#93;</span></code></pre>

<h2>Selecting the select method</h2>

<p>Let&#8217;s now have a quick look at the code that selects the poll/select implementation. Python 2.6 
has epoll support in the standard library, which is sniffed with <code>hasattr(</code>) on the <code>select</code> module.
If on python &lt; 2.6, Tornado will try to use its on C epoll module. You can find its sources in the
<code>tornado/epoll.c</code> file. Finally, if that fails (epoll is specific to Linux), it will fallback to
selec. <code>_Select</code> and <code>_EPoll</code> classes are wrappers for 
emulating the <code>select.epoll</code> API. Before doing your benchmarks, make sure you use <code>epoll</code>, because <code>select</code>
has poor performance with large sets of file descriptors.</p>

<pre class="lang-python"><code><span class="co1"># Choose a poll implementation. Use epoll if it is available, fall back to</span><br />
<span class="co1"># select() for non-Linux platforms</span><br />
<span class="kw1">if</span> <span class="kw2">hasattr</span><span class="br0">&#40;</span><span class="kw3">select</span>, <span class="st0">&quot;epoll&quot;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="co1"># Python 2.6+ on Linux</span><br />
&nbsp; &nbsp; _poll = <span class="kw3">select</span>.<span class="me1">epoll</span><br />
<span class="kw1">else</span>:<br />
&nbsp; &nbsp; <span class="kw1">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># Linux systems with our C module installed</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">import</span> epoll<br />
&nbsp; &nbsp; &nbsp; &nbsp; _poll = _EPoll<br />
&nbsp; &nbsp; <span class="kw1">except</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># All other systems</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">import</span> <span class="kw3">sys</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="st0">&quot;linux&quot;</span> <span class="kw1">in</span> <span class="kw3">sys</span>.<span class="kw3">platform</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">logging</span>.<span class="me1">warning</span><span class="br0">&#40;</span><span class="st0">&quot;epoll module not found; using select()&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; _poll = _Select</code></pre>

<p>With this, we&#8217;ve covered most of the <code>IOLoop</code> module. As advertised, it is indeed a 
nice and simple piece of code.</p>

<h2>From sockets to streams</h2>

<p>Let&#8217;s have a look now at the 
<a href="http://github.com/facebook/tornado/blob/master/tornado/iostream.py#L25">IOStream</a> module.
Its purpose is to provide a small level of abstraction over nonblocking sockets, by
offering three functions:</p>

<ul>
<li><code>read_until()</code>, which reads from the socket until it finds a given string. This is
convenient for reading the HTTP headers until the empty line delimiter. </li>
<li><code>read_bytes()</code>, which reads a give number of bytes from the socket. This is convenient
for reading the body of the HTTP message.</li>
<li><code>write()</code> which writes a given buffer to the socket and keeps retrying until the whole
buffer is sent.</li>
</ul>

<p>All of them can call a callback when they are done, in asynchronous style.</p>

<p>The <code>write()</code> implementation buffers the data provided by the caller and 
writes it whenever <code>IOLoop</code> calls its handler, because the socket is ready for writing:</p>

<pre class="lang-python"><code><span class="kw1">def</span> write<span class="br0">&#40;</span><span class="kw2">self</span>, data, callback=<span class="kw2">None</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;&quot;Write the given data to this stream.<br />
<br />
&nbsp; &nbsp; If callback is given, we call it when all of the buffered write<br />
&nbsp; &nbsp; data has been successfully written to the stream. If there was<br />
&nbsp; &nbsp; previously buffered write data and an old write callback, that<br />
&nbsp; &nbsp; callback is simply overwritten with this new callback.<br />
&nbsp; &nbsp; &quot;&quot;&quot;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>._check_closed<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>._write_buffer += data<br />
&nbsp; &nbsp; <span class="kw2">self</span>._add_io_state<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">io_loop</span>.<span class="me1">WRITE</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>._write_callback = callback</code></pre>

<p>The function that handles the <code>WRITE</code> event simply does <code>socket.send()</code> until <code>EWOULDBLOCK</code> 
is hit or the buffer is finished:</p>

<pre class="lang-python"><code><span class="kw1">def</span> _handle_write<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">while</span> <span class="kw2">self</span>._write_buffer:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; num_bytes = <span class="kw2">self</span>.<span class="kw3">socket</span>.<span class="me1">send</span><span class="br0">&#40;</span><span class="kw2">self</span>._write_buffer<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._write_buffer = <span class="kw2">self</span>._write_buffer<span class="br0">&#91;</span>num_bytes:<span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">except</span> <span class="kw3">socket</span>.<span class="me1">error</span>, e:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> e<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> <span class="kw1">in</span> <span class="br0">&#40;</span><span class="kw3">errno</span>.<span class="me1">EWOULDBLOCK</span>, <span class="kw3">errno</span>.<span class="me1">EAGAIN</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">logging</span>.<span class="me1">warning</span><span class="br0">&#40;</span><span class="st0">&quot;Write error on %d: %s&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="kw3">socket</span>.<span class="me1">fileno</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, e<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="kw1">not</span> <span class="kw2">self</span>._write_buffer <span class="kw1">and</span> <span class="kw2">self</span>._write_callback:<br />
&nbsp; &nbsp; &nbsp; &nbsp; callback = <span class="kw2">self</span>._write_callback<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._write_callback = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; callback<span class="br0">&#40;</span><span class="br0">&#41;</span></code></pre>

<p>Reading does the reverse process. The read event handler keeps reading until enough
is gathered in the read buffer. This means either it has the required length (if 
<code>read_bytes()</code>) or it contains the requested delimiter (if <code>read_until()</code>):</p>

<pre class="lang-python"><code><span class="kw1">def</span> _handle_read<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">chunk</span> = <span class="kw2">self</span>.<span class="kw3">socket</span>.<span class="me1">recv</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">read_chunk_size</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">except</span> <span class="kw3">socket</span>.<span class="me1">error</span>, e:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> e<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> <span class="kw1">in</span> <span class="br0">&#40;</span><span class="kw3">errno</span>.<span class="me1">EWOULDBLOCK</span>, <span class="kw3">errno</span>.<span class="me1">EAGAIN</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">logging</span>.<span class="me1">warning</span><span class="br0">&#40;</span><span class="st0">&quot;Read error on %d: %s&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="kw3">socket</span>.<span class="me1">fileno</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, e<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="kw1">not</span> <span class="kw3">chunk</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>._read_buffer += <span class="kw3">chunk</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">len</span><span class="br0">&#40;</span><span class="kw2">self</span>._read_buffer<span class="br0">&#41;</span> <span class="sy0">&gt;</span>= <span class="kw2">self</span>.<span class="me1">max_buffer_size</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">logging</span>.<span class="me1">error</span><span class="br0">&#40;</span><span class="st0">&quot;Reached maximum read buffer size&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">self</span>._read_bytes:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">len</span><span class="br0">&#40;</span><span class="kw2">self</span>._read_buffer<span class="br0">&#41;</span> <span class="sy0">&gt;</span>= <span class="kw2">self</span>._read_bytes:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; num_bytes = <span class="kw2">self</span>._read_bytes<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; callback = <span class="kw2">self</span>._read_callback<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._read_callback = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._read_bytes = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; callback<span class="br0">&#40;</span><span class="kw2">self</span>._consume<span class="br0">&#40;</span>num_bytes<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">elif</span> <span class="kw2">self</span>._read_delimiter:<br />
&nbsp; &nbsp; &nbsp; &nbsp; loc = <span class="kw2">self</span>._read_buffer.<span class="me1">find</span><span class="br0">&#40;</span><span class="kw2">self</span>._read_delimiter<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> loc <span class="sy0">!</span>= -<span class="nu0">1</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; callback = <span class="kw2">self</span>._read_callback<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; delimiter_len = <span class="kw2">len</span><span class="br0">&#40;</span><span class="kw2">self</span>._read_delimiter<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._read_callback = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._read_delimiter = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; callback<span class="br0">&#40;</span><span class="kw2">self</span>._consume<span class="br0">&#40;</span>loc + delimiter_len<span class="br0">&#41;</span><span class="br0">&#41;</span></code></pre>

<p>The <code>_consume()</code> function, that is used above, makes sure that no more that what was 
requested is taken out of the stream, and subsequent reads will get the immediate 
next bytes:</p>

<pre class="lang-python"><code><span class="kw1">def</span> _consume<span class="br0">&#40;</span><span class="kw2">self</span>, loc<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; result = <span class="kw2">self</span>._read_buffer<span class="br0">&#91;</span>:loc<span class="br0">&#93;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>._read_buffer = <span class="kw2">self</span>._read_buffer<span class="br0">&#91;</span>loc:<span class="br0">&#93;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> result</code></pre>

<p>Also worth noting in the <code>_handle_read()</code> function above is the capping of the 
read buffer at <code>self.max_buffer_size</code>. The default value for it is 100MB, which 
seems a bit large to me. For example, if an attacker makes just 100 connections 
to the server and keeps pushing headers to it without the end headers delimiter, 
Tornado will need <strong>10 GB of RAM</strong> to serve the requests. 
 Even if the RAM is not a problem, the copying operations done with a buffer of this size (like in the 
<code>_consume()</code> method above) will likely overload the server. Note also how <code>_handle_read()</code>
searches the delimiter in the whole buffer on each iteration, so if the attacker sends
the huge data in small chunks, the server has to do a lot of searches. Bottom of line, 
you might want to tune this parameter unless you really expect requests that big and you have
the hardware for it.</p>

<h2>The HTTP server</h2>

<p>Armed with the <code>IOLoop</code> and <code>IOStream</code> modules, writing an 
asynchronous HTTP server is just one step away, and that step is done in
<a href="http://github.com/facebook/tornado/blob/master/tornado/httpserver.py#L31">httpserver.py</a>.</p>

<p>The <code>HTTPServer</code> class itself only does the accepting of the new connections by adding
their sockets to the IOLoop. The listening socket itself is part of IOLoop, as seen in
the <code>listen()</code> method:</p>

<pre class="lang-python"><code><span class="kw1">def</span> listen<span class="br0">&#40;</span><span class="kw2">self</span>, port, address=<span class="st0">&quot;&quot;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">assert</span> <span class="kw1">not</span> <span class="kw2">self</span>._socket<br />
&nbsp; &nbsp; <span class="kw2">self</span>._socket = <span class="kw3">socket</span>.<span class="br0">&#40;</span><span class="kw3">socket</span>.<span class="me1">AF_INET</span>, <span class="kw3">socket</span>.<span class="me1">SOCK_STREAM</span>, <span class="nu0">0</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; flags = <span class="kw3">fcntl</span>.<span class="kw3">fcntl</span><span class="br0">&#40;</span><span class="kw2">self</span>._socket.<span class="me1">fileno</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, <span class="kw3">fcntl</span>.<span class="me1">F_GETFD</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; flags |= <span class="kw3">fcntl</span>.<span class="me1">FD_CLOEXEC</span><br />
&nbsp; &nbsp; <span class="kw3">fcntl</span>.<span class="kw3">fcntl</span><span class="br0">&#40;</span><span class="kw2">self</span>._socket.<span class="me1">fileno</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, <span class="kw3">fcntl</span>.<span class="me1">F_SETFD</span>, flags<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>._socket.<span class="me1">setsockopt</span><span class="br0">&#40;</span><span class="kw3">socket</span>.<span class="me1">SOL_SOCKET</span>, <span class="kw3">socket</span>.<span class="me1">SO_REUSEADDR</span>, <span class="nu0">1</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>._socket.<span class="me1">setblocking</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>._socket.<span class="me1">bind</span><span class="br0">&#40;</span><span class="br0">&#40;</span>address, port<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>._socket.<span class="me1">listen</span><span class="br0">&#40;</span><span class="nu0">128</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">io_loop</span>.<span class="me1">add_handler</span><span class="br0">&#40;</span><span class="kw2">self</span>._socket.<span class="me1">fileno</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, <span class="kw2">self</span>._handle_events,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw2">self</span>.<span class="me1">io_loop</span>.<span class="me1">READ</span><span class="br0">&#41;</span></code></pre>

<p>In addition to binding to given address and port, the code above sets the &#8220;close on exec&#8221; 
and &#8220;reuse address&#8221; flags. The former is useful in the case the application spawns new processes. In 
this case, we don&#8217;t want them to keep the socket open. The latter is useful for avoiding the
&#8220;Address already in use&#8221; error when restarting the server.</p>

<p>As you can see, the connection backlog is set to 128. This means that if 128 connection are waiting to
be accepted, new connections will be rejected until the server has time to accept some of them. 
I suggest trying to increase this one when doing benchmarks, as it directly affects when the new 
connections are dropped.</p>

<p>The <code>_handle_events()</code> handler, registered above, accepts the new connection, creates the <code>IOStream</code>
associated with the socket and starts a <code>HTTPConnection</code> class, which is responsible for the
rest of the interaction with it:</p>

<pre class="lang-python"><code><span class="kw1">def</span> _handle_events<span class="br0">&#40;</span><span class="kw2">self</span>, fd, events<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">while</span> <span class="kw2">True</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; connection, address = <span class="kw2">self</span>._socket.<span class="me1">accept</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">except</span> <span class="kw3">socket</span>.<span class="me1">error</span>, e:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> e<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> <span class="kw1">in</span> <span class="br0">&#40;</span><span class="kw3">errno</span>.<span class="me1">EWOULDBLOCK</span>, <span class="kw3">errno</span>.<span class="me1">EAGAIN</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">raise</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stream = iostream.<span class="me1">IOStream</span><span class="br0">&#40;</span>connection, io_loop=<span class="kw2">self</span>.<span class="me1">io_loop</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HTTPConnection<span class="br0">&#40;</span>stream, address, <span class="kw2">self</span>.<span class="me1">request_callback</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw2">self</span>.<span class="me1">no_keep_alive</span>, <span class="kw2">self</span>.<span class="me1">xheaders</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">except</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">logging</span>.<span class="me1">error</span><span class="br0">&#40;</span><span class="st0">&quot;Error in connection callback&quot;</span>, exc_info=<span class="kw2">True</span><span class="br0">&#41;</span></code></pre>

<p>Note that this method accepts all the pending connections in a single iteration. It stays in 
the <code>while True</code> loop until <code>EWOULDBLOCK</code> is returned, which means that there are no more 
new connections pending to be accepted.</p>

<p>The <code>HTTPConnection</code> class starts parsing the HTTP headers right in its <code>__init__()</code> method:</p>

<pre class="lang-python"><code><span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span>, stream, address, request_callback, no_keep_alive=<span class="kw2">False</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;xheaders=<span class="kw2">False</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">stream</span> = stream<br />
&nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">address</span> = address<br />
&nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">request_callback</span> = request_callback<br />
&nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">no_keep_alive</span> = no_keep_alive<br />
&nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">xheaders</span> = xheaders<br />
&nbsp; &nbsp; <span class="kw2">self</span>._request = <span class="kw2">None</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>._request_finished = <span class="kw2">False</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">stream</span>.<span class="me1">read_until</span><span class="br0">&#40;</span><span class="st0">&quot;rnrn&quot;</span>, <span class="kw2">self</span>._on_headers<span class="br0">&#41;</span></code></pre>

<p>If you&#8217;re wondering what <code>xheaders</code> parameter means, see this comment:</p>

<pre><code>If xheaders is True, we support the X-Real-Ip and X-Scheme headers,
which override the remote IP and HTTP scheme for all requests. These
headers are useful when running Tornado behind a reverse proxy or
load balancer.
</code></pre>

<p>The <code>_on_headers()</code> callback parses the headers and uses <code>read_bytes()</code> to read the
content of the request, if present. The <code>_on_request_body()</code> callback parses the <code>POST</code> 
arguments and then calls the application callback:</p>

<pre class="lang-python"><code><span class="kw1">def</span> _on_headers<span class="br0">&#40;</span><span class="kw2">self</span>, data<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; eol = data.<span class="me1">find</span><span class="br0">&#40;</span><span class="st0">&quot;rn&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; start_line = data<span class="br0">&#91;</span>:eol<span class="br0">&#93;</span><br />
&nbsp; &nbsp; method, uri, version = start_line.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">&quot; &quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="kw1">not</span> version.<span class="me1">startswith</span><span class="br0">&#40;</span><span class="st0">&quot;HTTP/&quot;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">raise</span> <span class="kw2">Exception</span><span class="br0">&#40;</span><span class="st0">&quot;Malformed HTTP version in HTTP Request-Line&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; headers = HTTPHeaders.<span class="me1">parse</span><span class="br0">&#40;</span>data<span class="br0">&#91;</span>eol:<span class="br0">&#93;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>._request = HTTPRequest<span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; connection=<span class="kw2">self</span>, method=method, uri=uri, version=version,<br />
&nbsp; &nbsp; &nbsp; &nbsp; headers=headers, remote_ip=<span class="kw2">self</span>.<span class="me1">address</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span><br />
<br />
&nbsp; &nbsp; content_length = headers.<span class="me1">get</span><span class="br0">&#40;</span><span class="st0">&quot;Content-Length&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> content_length:<br />
&nbsp; &nbsp; &nbsp; &nbsp; content_length = <span class="kw2">int</span><span class="br0">&#40;</span>content_length<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> content_length <span class="sy0">&gt;</span> <span class="kw2">self</span>.<span class="me1">stream</span>.<span class="me1">max_buffer_size</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">raise</span> <span class="kw2">Exception</span><span class="br0">&#40;</span><span class="st0">&quot;Content-Length too long&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> headers.<span class="me1">get</span><span class="br0">&#40;</span><span class="st0">&quot;Expect&quot;</span><span class="br0">&#41;</span> == <span class="st0">&quot;100-continue&quot;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">stream</span>.<span class="me1">write</span><span class="br0">&#40;</span><span class="st0">&quot;HTTP/1.1 100 (Continue)rnrn&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">stream</span>.<span class="me1">read_bytes</span><span class="br0">&#40;</span>content_length, <span class="kw2">self</span>._on_request_body<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span><br />
<br />
&nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">request_callback</span><span class="br0">&#40;</span><span class="kw2">self</span>._request<span class="br0">&#41;</span><br />
<br />
<span class="kw1">def</span> _on_request_body<span class="br0">&#40;</span><span class="kw2">self</span>, data<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw2">self</span>._request.<span class="me1">body</span> = data<br />
&nbsp; &nbsp; content_type = <span class="kw2">self</span>._request.<span class="me1">headers</span>.<span class="me1">get</span><span class="br0">&#40;</span><span class="st0">&quot;Content-Type&quot;</span>, <span class="st0">&quot;&quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">self</span>._request.<span class="me1">method</span> == <span class="st0">&quot;POST&quot;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> content_type.<span class="me1">startswith</span><span class="br0">&#40;</span><span class="st0">&quot;application/x-www-form-urlencoded&quot;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; arguments = <span class="kw3">cgi</span>.<span class="me1">parse_qs</span><span class="br0">&#40;</span><span class="kw2">self</span>._request.<span class="me1">body</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> name, values <span class="kw1">in</span> arguments.<span class="me1">iteritems</span><span class="br0">&#40;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; values = <span class="br0">&#91;</span>v <span class="kw1">for</span> v <span class="kw1">in</span> values <span class="kw1">if</span> v<span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> values:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>._request.<span class="me1">arguments</span>.<span class="me1">setdefault</span><span class="br0">&#40;</span>name, <span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>.<span class="me1">extend</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; values<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">elif</span> content_type.<span class="me1">startswith</span><span class="br0">&#40;</span><span class="st0">&quot;multipart/form-data&quot;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; boundary = content_type<span class="br0">&#91;</span><span class="nu0">30</span>:<span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> boundary: <span class="kw2">self</span>._parse_mime_body<span class="br0">&#40;</span>boundary, data<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">request_callback</span><span class="br0">&#40;</span><span class="kw2">self</span>._request<span class="br0">&#41;</span></code></pre>

<p>Writing the answer to the request is handled through the <code>HTTPRequest</code> class, which you can 
see instantiated in the <code>_on_headers()</code> method above. It just proxies the write to the 
stream object.</p>

<pre class="lang-python"><code><span class="kw1">def</span> write<span class="br0">&#40;</span><span class="kw2">self</span>, <span class="kw3">chunk</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="kw1">assert</span> <span class="kw2">self</span>._request, <span class="st0">&quot;Request closed&quot;</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">stream</span>.<span class="me1">write</span><span class="br0">&#40;</span><span class="kw3">chunk</span>, <span class="kw2">self</span>._on_write_complete<span class="br0">&#41;</span></code></pre>

<h2>To be continued?</h2>

<p>With this, I covered all the way from the bare sockets to the application layer.
This should give you a pretty clear image of how Tornado works inside. All in all,
I would say it was a pleasant code hike which I hope you enjoyed as well.</p>

<p>There are still large parts of the framework that remain unexplored, 
like <a href="http://github.com/facebook/tornado/blob/master/tornado/web.py#L17">wep.py</a>, 
which is actually what your application is interacting with, or the <a href="http://github.com/facebook/tornado/blob/master/tornado/template.py">template engine</a>.
If there is enough interest, I&#8217;ll cover those parts as well. Encourage me by subscribing
to my <a href="http://golubenco.org/feed/">RSS feed</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://golubenco.org/2009/09/19/understanding-the-code-inside-tornado-the-asynchronous-web-server-powering-friendfeed/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Reference counting tutorial</title>
		<link>http://golubenco.org/2007/07/29/reference-counting-tutorial/</link>
		<comments>http://golubenco.org/2007/07/29/reference-counting-tutorial/#comments</comments>
		<pubDate>Sun, 29 Jul 2007 22:39:13 +0000</pubDate>
		<dc:creator>tsg</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[reference counting]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://golubenco.org/blog/reference-counting-tutorial/</guid>
		<description><![CDATA[If you&#8217;re doing multi-threaded programs in C or C++ you really should get a good handle on reference counting. The Linux coding style says it [btw, if you haven't read that, do it now. Go on, I'll wait.]: Remember: if another thread can find your data structure, and you don&#8217;t have a reference count on [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re doing multi-threaded programs in C or C++ you really should get a good handle on reference counting. The <a href="http://lxr.linux.no/source/Documentation/CodingStyle">Linux coding style</a> says it [btw, if you haven't read that, do it now. Go on, I'll wait.]:</p>

<blockquote>
Remember: if another thread can find your data structure, and you don&#8217;t have a reference count on it, you almost certainly have a bug.
</blockquote>

<p>The solution I will present is, if not a <i>design pattern</i> (sounds too buzzy), at least good practice.  After discovering it, I changed a lot of my code to use it consistently, and found out that makes the code simpler and less prone to synchronizations bugs, memory leaks  and <a href="http://en.wikipedia.org/wiki/Profiler_%28computer_science%29#Simple_manual_technique">slugs</a>. Get it right, and you won&#8217;t miss the GC too much.</p>

<p>I said a C or C++ application because the languages with embedded Garbage Collectors solve this transparently for you. Not for free, though, but for (many) extra CPU cycles.</p>

<h4>Sample Problem</h4>

<p>Let&#8217;s take something simple:</p>

<blockquote>
In a C/C++ application, you have a global list [| collection | hashtable | tree] of objects that can be accessed by multiple threads. Each object has an unique identifier. Each thread can add a new object to the list or get an object to modify it or delete it.
</blockquote>

<p>Sounds basic, doesn&#8217;t it? Well, you can really shoot yourself in the foot with it. Special care must be taken when deleting objects, because other threads might currently work with that object or iterate through the global list.</p>

<h4>Disclaimers</h4>

<p>The method is <i>Not Invented Here &#8482;</i>. I saw it in the Linux code, to name one, and is popular between experienced programmers. I haven&#8217;t seen many tutorials about it, though. BTW, this article might be useful for you if you&#8217;re trying to understand how reference counting is used in the Linux kernel.</p>

<p>The code snippets are in C with the pthread library, but better consider them as pseudo-code. They&#8217;re meant as starting points, not as ready for copy&#8217;n'paste. I have never tried them, so I would be surprised if they even compile cleanly.</p>

<h4>Solution</h4>

<p>Over time, I found this minimal API to be convenient:</p>

<pre class="lang-c"><code>obj_t<span class="sy0">*</span> obj_lookup<span class="br0">&#40;</span><span class="kw4">int</span> id<span class="br0">&#41;</span><span class="sy0">;</span><br />
obj_t<span class="sy0">*</span> obj_lookup_or_create<span class="br0">&#40;</span><span class="kw4">int</span> id<span class="sy0">,</span> <span class="kw4">int</span> <span class="sy0">*</span>isnew<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw4">void</span> obj_kill<span class="br0">&#40;</span>obj_t <span class="sy0">*</span>obj<span class="br0">&#41;</span><span class="sy0">;</span></code></pre>

<p>The obj_lookup() function needs no introduction, it simply searches an object by id in the global list. If not found, returns NULL.</p>

<p>There is no explicit create function because we cannot have two objects with the same id, and the API reflects this. The obj_lookup_or_create() searches for an object with the specified id, and if not found, creates one and returns it. It will return NULL only in case of error while creating. The isnew output parameter is used to let the caller know if the object was created by this operation or not.</p>

<p>The obj_kill() function removes the object from the global list and releases it.</p>

<p>Since I mentioned multi-threaded, we need to think about locking. Having a single Big Lock (for short BFL <img src='http://golubenco.org/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  ) that protects both the global lists and all the objects is simple. It also doesn&#8217;t leave room for many bugs, but all operations are serialized and performance drops. I consider this as not an option. [In fact, there's more than a performance issue: I think it's a petty that many GUI applications choose this method and we get unresponsive applications when one thread blocks for a long time with the BFL taken.]</p>

<p>It&#8217;s better to lock each object individually and have another lock for accessing the global list. Operations on different objects can be made in parallel, so we take advantage of all those cores from the new machines.</p>

<h4>The buggy way</h4>

<p>I would like to start with a naive implementation, to better identify the issue:</p>

<pre class="lang-c"><code><span class="kw4">static</span> list_t <span class="sy0">*</span>_list<span class="sy0">;</span><br />
<span class="kw4">static</span> pthread_mutex_t <span class="sy0">*</span>_mutex<span class="sy0">;</span><br />
<br />
<br />
type def obj <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw4">int</span> id<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw4">void</span> <span class="sy0">*</span>value<span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; pthread_mutex_t mutex<span class="sy0">;</span><br />
<span class="br0">&#125;</span> obj_t<span class="sy0">;</span><br />
<br />
<br />
obj_t<span class="sy0">*</span> lookup_or_create<span class="br0">&#40;</span><span class="kw4">int</span> id<span class="sy0">,</span> <span class="kw4">int</span> <span class="sy0">*</span>isnew<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; obj_t <span class="sy0">*</span>obj<span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; pthread_mutex_lock<span class="br0">&#40;</span><span class="sy0">&amp;</span>_mutex<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; list_for_each<span class="br0">&#40;</span>obj<span class="sy0">,</span> list<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>obj<span class="sy0">-&gt;</span>id <span class="sy0">==</span> id<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PMUTEX_UNLOCK<span class="br0">&#40;</span><span class="sy0">&amp;</span>_mutex<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> obj<span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; <span class="coMULTI">/* not found, create */</span><br />
&nbsp; &nbsp; obj <span class="sy0">=</span> obj_new<span class="br0">&#40;</span>id<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; list_add<span class="br0">&#40;</span>list<span class="sy0">,</span> obj<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; pthread_mutex_unlock<span class="br0">&#40;</span><span class="sy0">&amp;</span>_mutex<span class="br0">&#41;</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">return</span> obj<span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> obj_kill<span class="br0">&#40;</span>obj_t <span class="sy0">*</span>obj<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; pthread_mutex_lock<span class="br0">&#40;</span><span class="sy0">&amp;</span>_mutex<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; list_del<span class="br0">&#40;</span>list<span class="sy0">,</span> obj<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; pthread_mutex_unlock<span class="br0">&#40;</span><span class="sy0">&amp;</span>_mutex<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></code></pre>

<p>The obj_lookup() is too similar to the obj_lookup_or_create() to be worth adding it. A possible usage (again, naive) would be:</p>

<pre class="lang-c"><code><span class="kw4">int</span> process_obj_with_id<span class="br0">&#40;</span><span class="kw4">int</span> id<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; obj_t <span class="sy0">*</span>obj<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw4">int</span> isnew<span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; obj <span class="sy0">=</span> lookup_or_create<span class="br0">&#40;</span>id<span class="sy0">,</span> <span class="sy0">&amp;</span>isnew<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>obj<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="sy0">-</span><span class="nu0">1</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; pthread_mutex_lock<span class="br0">&#40;</span><span class="sy0">&amp;</span>obj<span class="sy0">-&gt;</span>mutex<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; process_object<span class="br0">&#40;</span>obj<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>should_be_dead<span class="br0">&#40;</span>obj<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; obj_kill<span class="br0">&#40;</span>obj<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; pthread_mutex_unlock<span class="br0">&#40;</span><span class="sy0">&amp;</span>obj<span class="sy0">-&gt;</span>mutex<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>obj_is_dead<span class="br0">&#40;</span>obj<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; free<span class="br0">&#40;</span>obj<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">0</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></code></pre>

<p>This function can be called by multiple threads concurentely, that was the whole point. The process_object() function do the actual job (whatever that is). The should_be_dead() is introduced only to suggest that the user can decide to delete the object at any point.</p>

<p>Can you spot the bug in the above code?</p>

<p>It&#8217;s easy, consider the following situation: two threads call the process_object_with_id() at the same time with the same id. An object with that id already exists. Both of them execute the lookup and get pointers to the object. One of the threads takes the lock, the other waits. So far, so good. But now, the first thread decides to delete the object and frees its memory. Oops. The second thread now has an invalid pointer to work with and will probably segfault.</p>

<p>You can try to work around it by using properties specific to the application or by locking tricks, but I wouldn&#8217;t recommend it. All you&#8217;ll get is buggy code. If you recognize this pattern, you should use</p>

<h4>The good way</h4>

<p>The good way is to use reference counting. Whenever you get a pointer to an object, increment its reference count. Whenever the pointer gets out of scope or it&#8217;s removed, decrement it. When the reference count of an object gets to zero, free it. Reference counting can be efficiently implemented with <a href=" http://golubenco.org/blog/atomic-operations/">atomic operations</a>:</p>

<pre class="lang-c"><code><span class="kw4">typedef</span> <span class="kw4">struct</span> obj <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw4">int</span> id<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw4">void</span> <span class="sy0">*</span>value<span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; pthread_mutex_t mutex<span class="sy0">;</span><br />
&nbsp; &nbsp; atomic_t ref<span class="sy0">;</span><br />
&nbsp; &nbsp; bool_t killed<span class="sy0">;</span><br />
<span class="br0">&#125;</span> obj_t<span class="sy0">;</span><br />
<br />
<br />
<span class="kw2">inline</span> <span class="kw4">void</span> obj_refinc<span class="br0">&#40;</span>obj_t <span class="sy0">*</span>obj<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; assert<span class="br0">&#40;</span>atomic_read<span class="br0">&#40;</span><span class="sy0">&amp;</span>obj<span class="sy0">-&gt;</span>ref<span class="br0">&#41;</span> <span class="sy0">&gt;</span> <span class="nu0">0</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; atomic_inc<span class="br0">&#40;</span><span class="sy0">&amp;</span>obj<span class="sy0">-&gt;</span>ref<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw2">inline</span> <span class="kw4">int</span> obj_refdec<span class="br0">&#40;</span>obj_t <span class="sy0">*</span>obj<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; assert<span class="br0">&#40;</span>obj<span class="sy0">-&gt;</span>killed<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>atomic_dec_and_test<span class="br0">&#40;</span><span class="sy0">&amp;</span>obj<span class="sy0">-&gt;</span>ref<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; free<span class="br0">&#40;</span>obj<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> TRUE<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> FALSE<span class="sy0">;</span><br />
<span class="br0">&#125;</span></code></pre>

<p>Things to note so far:</p>

<ul>
<li>The assert from the obj_refinc() function (line 13) is a nice bug trap: you can&#8217;t increment the reference count of an object if you don&#8217;t already have a pointer to it. Thus, the reference count <strong>must</strong> be greater than zero already.</li>
<li>The &#8216;killed&#8217; boolean for the obj structure is not always needed. It does, however, a good job against double deletion (see the obj_kill() function below), so I usually add it.</li>
<li>obj_refdec() returns TRUE if the object was deleted at this operations. This is also not strictly needed but it&#8217;s useful for bug trapping. If obj_refdec() returns TRUE, you <strong>know</strong> that accessing it from now on will cause problems.</li>
</ul>

<p>The rest of the interesting functions can be implemented like this:</p>

<pre class="lang-c"><code>obj_t<span class="sy0">*</span> lookup_or_create<span class="br0">&#40;</span><span class="kw4">int</span> id<span class="sy0">,</span> <span class="kw4">int</span> <span class="sy0">*</span>isnew<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; obj_t <span class="sy0">*</span>obj<span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; pthread_mutex_lock<span class="br0">&#40;</span><span class="sy0">&amp;</span>_mutex<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; list_for_each<span class="br0">&#40;</span>obj<span class="sy0">,</span> list<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>obj<span class="sy0">-&gt;</span>killed <span class="sy0">&amp;&amp;</span> obj<span class="sy0">-&gt;</span>id <span class="sy0">==</span> id<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; obj_refinc<span class="br0">&#40;</span>obj<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pthread_mutex_unlock<span class="br0">&#40;</span><span class="sy0">&amp;</span>_mutex<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> obj<span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; <span class="coMULTI">/* not found, create */</span><br />
&nbsp; &nbsp; obj <span class="sy0">=</span> obj_new<span class="br0">&#40;</span>id<span class="br0">&#41;</span><span class="sy0">;</span> <span class="coMULTI">/* sets reference count to 1 */</span><br />
<br />
&nbsp; &nbsp; list_add<span class="br0">&#40;</span>list<span class="sy0">,</span> obj<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; obj_refinc<span class="br0">&#40;</span>obj<span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; pthread_mutex_unlock<span class="br0">&#40;</span><span class="sy0">&amp;</span>_mutex<span class="br0">&#41;</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">return</span> obj<span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">void</span> obj_kill<span class="br0">&#40;</span>obj_t <span class="sy0">*</span>obj<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>obj<span class="sy0">-&gt;</span>killed<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; obj<span class="sy0">-&gt;</span>killed <span class="sy0">=</span> TRUE<span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; pthread_mutex_lock<span class="br0">&#40;</span><span class="sy0">&amp;</span>_mutex<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; list_del<span class="br0">&#40;</span>list<span class="sy0">,</span> obj<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; pthread_mutex_unlock<span class="br0">&#40;</span><span class="sy0">&amp;</span>_mutex<span class="br0">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>obj_decref<span class="br0">&#40;</span>obj<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; assert<span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="coMULTI">/* BUG: the ref count got to zero to soon */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw4">int</span> process_obj_with_id<span class="br0">&#40;</span><span class="kw4">int</span> id<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; obj_t <span class="sy0">*</span>obj<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw4">int</span> isnew<span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; obj <span class="sy0">=</span> lookup_or_create<span class="br0">&#40;</span>id<span class="sy0">,</span> <span class="sy0">&amp;</span>isnew<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>obj<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="sy0">-</span><span class="nu0">1</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; pthread_mutex_lock<span class="br0">&#40;</span><span class="sy0">&amp;</span>obj<span class="sy0">-&gt;</span>mutex<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>obj<span class="sy0">-&gt;</span>killed<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; process_object<span class="br0">&#40;</span>obj<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>should_be_dead<span class="br0">&#40;</span>obj<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; obj_kill<span class="br0">&#40;</span>obj<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; pthread_mutex_unlock<span class="br0">&#40;</span><span class="sy0">&amp;</span>obj<span class="sy0">-&gt;</span>mutex<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; obj_refdec<span class="br0">&#40;</span>obj<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">0</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></code></pre>

<p>Note that:
 * When creating an object (line 16), the reference count is set to 1. This is to reflect the initial pointer, as returned by malloc, that we have on the object.
 * When the object is added to the global lists, it&#8217;s reference count is incremented (line 19).
 * Every time a thread gets a pointer of the object from the global list, it increments its reference count (line 8), and every time the pointer gets out of scope, the reference count <strong>must</strong> be decremented (line 57).
 * obj_kill() checks the return code of the obj_refdec() (line 35). It is impossible to have a reference count of zero after this call, because there is at least one more pointer to the object (the *obj from process_obj_with_id, in this case). 
 * Since after the call to lookup_or_create() (line 46) the reference count of obj is grater than one, the object will not be freed by another thread until we ref dec..
 * The &#8216;killed&#8217; flag, however, needs to be checked after getting the lock (line 51) because other thread might have set it before we got the lock.
 * After we are done with the object (usually when the pointer goes out of scope) we need to call obj_decref() (line 57).</p>
]]></content:encoded>
			<wfw:commentRss>http://golubenco.org/2007/07/29/reference-counting-tutorial/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Type safe hooks in C</title>
		<link>http://golubenco.org/2007/06/21/type-safe-hooks-in-c/</link>
		<comments>http://golubenco.org/2007/06/21/type-safe-hooks-in-c/#comments</comments>
		<pubDate>Thu, 21 Jun 2007 22:02:03 +0000</pubDate>
		<dc:creator>tsg</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[hooks]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[type safe]]></category>

		<guid isPermaLink="false">http://golubenco.org/blog/type-safe-hooks-in-c/</guid>
		<description><![CDATA[I sometimes envy the C++ guys for having simple APIs for the signal-slot mechanism. While the signal and slots were designed by the people doing GUI toolkits &#8212; with the main credit going to the Qt project &#8212; they can be useful as a general inter-module communication mechanism in any software project. Signals provide loose [...]]]></description>
			<content:encoded><![CDATA[<p>I sometimes envy the C++ guys for having simple APIs for the <a href="http://en.wikipedia.org/wiki/Signals_and_slots">signal-slot</a> mechanism. While the signal and slots were designed by the people doing GUI toolkits &#8212; with the main credit going to the <a href=" http://doc.trolltech.com/4.1/signalsandslots.html">Qt project</a> &#8212; they can be useful as a general inter-module communication mechanism in any software project.</p>

<p>Signals provide <strong>loose module coupling</strong>, which is crucial for good design. All you need to declare are the arguments of the signal, and then any module is free to generate them and any other module is free to receive them. If the module sending signals is freed, no problem, the receiver will simply not receive any more signals. If the receiver module is freed, again no problem, the signals will be simply ignored. It&#8217;s that simple.</p>

<p>Another property of the signals is that they are <strong>type safe</strong>, meaning that if the type of the arguments of a signal changes and you fail to update all receivers, you will get compile time errors instead of weird hard-to-find run-time bugs. The type unsafeness for callbacks is too often ignored by C programmers, and it generates a good share of bugs.</p>

<p>The reason I said I envy C++ programmers is that the mechanism can&#8217;t be elegantly implemented in  C, because C lacks generics and function overloading. But fear not, if we know what we aim for, we can get pretty close to anything in C. Here is how I do it: a <strong>hook</strong> is a list of pointers to callback functions. The receivers register their callbacks by adding them to the list. When the hook is called, i.e. the signal is generated, it will call all the callbacks from its list. Pretty simple so far, but how do you provide type safeness? you ask. With wrappers and macros.</p>

<p>Lets suppose the hook structure looks something like:</p>

<pre class="lang-c"><code><span class="kw4">typedef</span> <span class="kw4">struct</span> hook_cb <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw4">void</span> <span class="br0">&#40;</span><span class="sy0">*</span>f<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw4">struct</span> hook <span class="sy0">*</span>next<span class="sy0">;</span><br />
<span class="br0">&#125;</span> hook_cb_t<span class="sy0">;</span><br />
<br />
<span class="kw4">typedef</span> <span class="kw4">struct</span> hook <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw4">struct</span> hook <span class="sy0">*</span>hooks<span class="sy0">;</span><br />
&nbsp; &nbsp; pthread_rwlock_t <span class="sy0">*</span>lock<span class="sy0">;</span><br />
<span class="br0">&#125;</span> hook_t<span class="sy0">;</span></code></pre>

<p>It&#8217;s basically the list of callbacks that I was talking about, protected by a read-write lock. We then need methods for registering and unregistering the callbacks. Here are the prototypes, you have the pleasure of doing the single-linked list insertion and removal on your own (or cheat with whatever library).</p>

<pre class="lang-c"><code><span class="coMULTI">/**<br />
&nbsp;* Adds f to the hook-&gt;hooks_cb list.<br />
&nbsp;*/</span><br />
<span class="kw4">int</span> hook_register_cb<span class="br0">&#40;</span>hook_t <span class="sy0">*</span>hook<span class="sy0">,</span> <span class="kw4">void</span><span class="br0">&#40;</span><span class="sy0">*</span>f<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="coMULTI">/**<br />
&nbsp;* Removes f from the hook-&gt;hooks_cb.<br />
&nbsp;*/</span><br />
<span class="kw4">int</span> hook_unregister_cb<span class="br0">&#40;</span>hook_t <span class="sy0">*</span>hook<span class="sy0">,</span> <span class="kw4">void</span><span class="br0">&#40;</span><span class="sy0">*</span>f<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></code></pre>

<p>So far everything is type unsafe. The type of the callback was just randomly chosen to look like a function. But the macro comes into play:</p>

<pre class="lang-c"><code><span class="co2">#define hook_call(hook, type, ... ) do { </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; hook_cb_t __cb<span class="sy0">;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; pthread_rwlock_rdlock<span class="br0">&#40;</span><span class="sy0">&amp;</span><span class="br0">&#40;</span>hook<span class="br0">&#41;</span><span class="sy0">-&gt;</span>lock<span class="br0">&#41;</span><span class="sy0">;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span>__cb <span class="sy0">=</span> <span class="br0">&#40;</span>hook<span class="br0">&#41;</span><span class="sy0">-&gt;</span>hooks_cb<span class="sy0">;</span> __cb<span class="sy0">;</span> __cb <span class="sy0">=</span> __cb<span class="sy0">-&gt;</span>next<span class="br0">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="br0">&#40;</span>type<span class="sy0">*</span><span class="br0">&#41;</span>__cb<span class="sy0">-&gt;</span>f<span class="br0">&#41;</span><span class="br0">&#40;</span>__VA_ARGS__<span class="br0">&#41;</span><span class="sy0">;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; pthread_rwlock_unlock<span class="br0">&#40;</span><span class="sy0">&amp;</span><span class="br0">&#40;</span>hook<span class="br0">&#41;</span><span class="sy0">-&gt;</span>lock<span class="br0">&#41;</span><span class="sy0">;</span> <br />
<span class="br0">&#125;</span> <span class="kw1">while</span><span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span></code></pre>

<p>This hook_call macro receives as arguments a pointer to the hook structure, the <strong>type of the callback</strong>, and a variable number of arguments.  It iterates through the callback list, casts the function pointers to the provided type and calls them with the macro arguments using the variadic macro for that. If the arguments don&#8217;t match the given function type, the compiler will report an error, which is all we ever wanted, actually.</p>

<p>For example, lets suppose we have a hook with two integer arguments. The callback type is:</p>

<pre class="lang-c"><code><span class="kw4">typedef</span> <span class="kw4">void</span><span class="br0">&#40;</span>my_callback_t<span class="br0">&#41;</span><span class="br0">&#40;</span><span class="kw4">int</span><span class="sy0">,</span> <span class="kw4">int</span><span class="sy0">,</span> <span class="kw4">float</span><span class="br0">&#41;</span><span class="sy0">;</span></code></pre>

<p>Then, the hook can be called with something like:</p>

<pre class="lang-c"><code>hooks_call<span class="br0">&#40;</span>hook<span class="sy0">,</span> my_callback_t<span class="sy0">,</span> <span class="nu0">3</span><span class="sy0">,</span> <span class="nu0">4</span><span class="br0">&#41;</span><span class="sy0">;</span></code></pre>

<p>As the careful reader will notice, this only solves half of the problem. If the receivers register callbacks of the wrong type, it will be called anyway and cause troubles. This is why when declaring hooks, I also create wrappers for the register routines. Extending the above example:</p>

<pre class="lang-c"><code><span class="kw2">inline</span> <span class="kw4">static</span> <span class="kw4">int</span> my_hook_register<span class="br0">&#40;</span> hook_t <span class="sy0">*</span>hook<span class="sy0">,</span> my_callback_t <span class="sy0">*</span>f <span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> hook_register<span class="br0">&#40;</span>hook<span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span><span class="br0">&#41;</span>f<span class="br0">&#41;</span> <span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="kw2">inline</span> <span class="kw4">static</span> <span class="kw4">int</span> my_hook_unregister<span class="br0">&#40;</span> hook_t <span class="sy0">*</span>hook<span class="sy0">,</span> my_callback_t <span class="sy0">*</span>f <span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> hooks_unregister<span class="br0">&#40;</span> hook<span class="sy0">,</span> <span class="br0">&#40;</span><span class="kw4">void</span><span class="sy0">*</span><span class="br0">&#41;</span>f <span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></code></pre>

<p>These 7 lines are the actual cost of type safeness. A fair price if you ask me. Especially since you can have callbacks with any number of arguments having any type. No need for casts in the callback, no need for packing structures, no need for documenting the type of the arguments. Things get simpler because the glue is centralized in the hook declaration.</p>

<p>Finally, a wrapper for the calling macro might also come handy to simplify the signal generators.</p>

<pre class="lang-c"><code><span class="kw2">inline</span> <span class="kw4">static</span> <span class="kw4">void</span> my_hook_call<span class="br0">&#40;</span>hook_t <span class="sy0">*</span>hook<span class="sy0">,</span> <span class="kw4">int</span> a<span class="sy0">,</span> <span class="kw4">int</span> b<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; hook_call<span class="br0">&#40;</span>hook<span class="sy0">,</span> my_callback_t<span class="sy0">,</span> a<span class="sy0">,</span> b <span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></code></pre>

<p>Useful? Found an error? Something not clear?
Leave a comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://golubenco.org/2007/06/21/type-safe-hooks-in-c/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Atomic Operations</title>
		<link>http://golubenco.org/2007/06/14/atomic-operations/</link>
		<comments>http://golubenco.org/2007/06/14/atomic-operations/#comments</comments>
		<pubDate>Thu, 14 Jun 2007 22:52:58 +0000</pubDate>
		<dc:creator>tsg</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[atomic]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[gcc]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://golubenco.org/blog/?p=7</guid>
		<description><![CDATA[&#8220;Where did atomic.h go?!?&#8221; ..was my surprised reaction when I compiled one of my applications in Debian Etch for the first time. It compiled with no problems on Sarge and on Gentoo, but couldn&#8217;t find the atomic.h header file on Etch. A bit confused, I asked my friend, and he didn&#8217;t seem to know at [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;Where did atomic.h go?!?&#8221;</p>

<p>..was my surprised reaction when I compiled one of my applications in Debian Etch for the first time. It compiled with no problems on Sarge and on Gentoo, but couldn&#8217;t find the atomic.h header file on Etch. A bit confused, I asked my <a href="http://google.com">friend</a>, and he didn&#8217;t seem to know at the first queries, so after I figured it out, I wrote this post.</p>

<p>First, to understand why was atomic.h removed, you should know the following:
 * The /usr/include/asm/atomic.h , as it is found on Debian Sarge is a <em>kernel</em> header, somehow cleaned up to compile well in user-space, but still a kernel header.
 * Including kernel headers in user-space is generally bad idea, unless you are using the kernel API (e.g. for an ioctl).
 * The <code>atomic.h</code> header, in particular, was not meant to be included in user-space. For example, if on a SMP machine you don&#8217;t compile with CONFIG_SMP, the operations will loose their atomicity. Even worse, on some architecture the atomic.h is completely broken in user-space because it&#8217;s working by disabling interrupts. <a href="http://lkml.org/lkml/2006/7/17/3">Here</a> is a LKML thread on the subject.
 * It&#8217;s Linux specific, other Unix-es might not have an equivalent.</p>

<p>Despite these things, many applications (e.g. <a href="http://bugs.mysql.com/bug.php?id=13621">mysql</a>) used the atomic.h because of the lack of alternatives. There is no equivalent in glibc. Some framework libraries, like <a href="http://developer.gnome.org/doc/API/2.2/glib/glib-Atomic-Operations.html">GLib</a> or <a href="http://apr.apache.org/docs/apr/0.9/group__apr__atomic.html">apr</a> have their own implementation for atomic operations but linking against them just for that doesn&#8217;t always make sense. Simulating them with pthread spin locks is not much of an option either, as much of the performance is wasted. Finally, maintaining assembly versions in each application is out of the question.</p>

<p>The <strong>good news</strong> is that now there is a good and portable solution: <a href="http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html">gcc atomic builtins</a>. Since they are provided by the compiler, who is our specialist in generating machine code, they are sure to be correct on all supported architectures and operating systems. In fact, it makes so much sense to me to have the atomic operations as a language extension that I&#8217;m surprised we had to wait until version 4.1 of gcc to see them implemented. The downsides are that (1) some old processor will not use them efficiently and (2) the API is a little cumbersome.</p>

<p>To get you going, here is an in-place replacement for the atomic.h header:</p>

<pre class="lang-c"><code><span class="co2">#ifndef _ATOMIC_H</span><br />
<span class="co2">#define _ATOMIC_H</span><br />
<br />
<span class="coMULTI">/**<br />
&nbsp;* Atomic type.<br />
&nbsp;*/</span><br />
<br />
<span class="kw4">typedef</span> <span class="kw4">struct</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw4">volatile</span> <span class="kw4">int</span> counter<span class="sy0">;</span><br />
<span class="br0">&#125;</span> atomic_t<span class="sy0">;</span><br />
<br />
<span class="co2">#define ATOMIC_INIT(i) &nbsp;{ (i) }</span><br />
<br />
<span class="coMULTI">/**<br />
&nbsp;* Read atomic variable<br />
&nbsp;* @param v pointer of type atomic_t<br />
&nbsp;*<br />
&nbsp;* Atomically reads the value of @v.<br />
&nbsp;*/</span><br />
<span class="co2">#define atomic_read(v) ((v)-&gt;counter)</span><br />
<br />
<span class="coMULTI">/**<br />
&nbsp;* Set atomic variable<br />
&nbsp;* @param v pointer of type atomic_t<br />
&nbsp;* @param i required value<br />
&nbsp;*/</span><br />
<span class="co2">#define atomic_set(v,i) (((v)-&gt;counter) = (i))</span><br />
<br />
<span class="coMULTI">/**<br />
&nbsp;* Add to the atomic variable<br />
&nbsp;* @param i integer value to add<br />
&nbsp;* @param v pointer of type atomic_t<br />
&nbsp;*/</span><br />
<span class="kw4">static</span> <span class="kw2">inline</span> <span class="kw4">void</span> atomic_add<span class="br0">&#40;</span> <span class="kw4">int</span> i<span class="sy0">,</span> atomic_t <span class="sy0">*</span>v <span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span>__sync_add_and_fetch<span class="br0">&#40;</span><span class="sy0">&amp;</span>v<span class="sy0">-&gt;</span>counter<span class="sy0">,</span> i<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="coMULTI">/**<br />
&nbsp;* Subtract the atomic variable<br />
&nbsp;* @param i integer value to subtract<br />
&nbsp;* @param v pointer of type atomic_t<br />
&nbsp;*<br />
&nbsp;* Atomically subtracts @i from @v.<br />
&nbsp;*/</span><br />
<span class="kw4">static</span> <span class="kw2">inline</span> <span class="kw4">void</span> atomic_sub<span class="br0">&#40;</span> <span class="kw4">int</span> i<span class="sy0">,</span> atomic_t <span class="sy0">*</span>v <span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span>__sync_sub_and_fetch<span class="br0">&#40;</span><span class="sy0">&amp;</span>v<span class="sy0">-&gt;</span>counter<span class="sy0">,</span> i<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="coMULTI">/**<br />
&nbsp;* Subtract value from variable and test result<br />
&nbsp;* @param i integer value to subtract<br />
&nbsp;* @param v pointer of type atomic_t<br />
&nbsp;*<br />
&nbsp;* Atomically subtracts @i from @v and returns<br />
&nbsp;* true if the result is zero, or false for all<br />
&nbsp;* other cases.<br />
&nbsp;*/</span><br />
<span class="kw4">static</span> <span class="kw2">inline</span> <span class="kw4">int</span> atomic_sub_and_test<span class="br0">&#40;</span> <span class="kw4">int</span> i<span class="sy0">,</span> atomic_t <span class="sy0">*</span>v <span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="sy0">!</span><span class="br0">&#40;</span>__sync_sub_and_fetch<span class="br0">&#40;</span><span class="sy0">&amp;</span>v<span class="sy0">-&gt;</span>counter<span class="sy0">,</span> i<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="coMULTI">/**<br />
&nbsp;* Increment atomic variable<br />
&nbsp;* @param v pointer of type atomic_t<br />
&nbsp;*<br />
&nbsp;* Atomically increments @v by 1.<br />
&nbsp;*/</span><br />
<span class="kw4">static</span> <span class="kw2">inline</span> <span class="kw4">void</span> atomic_inc<span class="br0">&#40;</span> atomic_t <span class="sy0">*</span>v <span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span>__sync_fetch_and_add<span class="br0">&#40;</span><span class="sy0">&amp;</span>v<span class="sy0">-&gt;</span>counter<span class="sy0">,</span> <span class="nu0">1</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="coMULTI">/**<br />
&nbsp;* @brief decrement atomic variable<br />
&nbsp;* @param v: pointer of type atomic_t<br />
&nbsp;*<br />
&nbsp;* Atomically decrements @v by 1. &nbsp;Note that the guaranteed<br />
&nbsp;* useful range of an atomic_t is only 24 bits.<br />
&nbsp;*/</span><br />
<span class="kw4">static</span> <span class="kw2">inline</span> <span class="kw4">void</span> atomic_dec<span class="br0">&#40;</span> atomic_t <span class="sy0">*</span>v <span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span>__sync_fetch_and_sub<span class="br0">&#40;</span><span class="sy0">&amp;</span>v<span class="sy0">-&gt;</span>counter<span class="sy0">,</span> <span class="nu0">1</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="coMULTI">/**<br />
&nbsp;* @brief Decrement and test<br />
&nbsp;* @param v pointer of type atomic_t<br />
&nbsp;*<br />
&nbsp;* Atomically decrements @v by 1 and<br />
&nbsp;* returns true if the result is 0, or false for all other<br />
&nbsp;* cases.<br />
&nbsp;*/</span><br />
<span class="kw4">static</span> <span class="kw2">inline</span> <span class="kw4">int</span> atomic_dec_and_test<span class="br0">&#40;</span> atomic_t <span class="sy0">*</span>v <span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">return</span> <span class="sy0">!</span><span class="br0">&#40;</span>__sync_sub_and_fetch<span class="br0">&#40;</span><span class="sy0">&amp;</span>v<span class="sy0">-&gt;</span>counter<span class="sy0">,</span> <span class="nu0">1</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="coMULTI">/**<br />
&nbsp;* @brief Increment and test<br />
&nbsp;* @param v pointer of type atomic_t<br />
&nbsp;*<br />
&nbsp;* Atomically increments @v by 1<br />
&nbsp;* and returns true if the result is zero, or false for all<br />
&nbsp;* other cases.<br />
&nbsp;*/</span><br />
<span class="kw4">static</span> <span class="kw2">inline</span> <span class="kw4">int</span> atomic_inc_and_test<span class="br0">&#40;</span> atomic_t <span class="sy0">*</span>v <span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="sy0">!</span><span class="br0">&#40;</span>__sync_add_and_fetch<span class="br0">&#40;</span><span class="sy0">&amp;</span>v<span class="sy0">-&gt;</span>counter<span class="sy0">,</span> <span class="nu0">1</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="coMULTI">/**<br />
&nbsp;* @brief add and test if negative<br />
&nbsp;* @param v pointer of type atomic_t<br />
&nbsp;* @param i integer value to add<br />
&nbsp;*<br />
&nbsp;* Atomically adds @i to @v and returns true<br />
&nbsp;* if the result is negative, or false when<br />
&nbsp;* result is greater than or equal to zero.<br />
&nbsp;*/</span><br />
<span class="kw4">static</span> <span class="kw2">inline</span> <span class="kw4">int</span> atomic_add_negative<span class="br0">&#40;</span> <span class="kw4">int</span> i<span class="sy0">,</span> atomic_t <span class="sy0">*</span>v <span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">return</span> <span class="br0">&#40;</span>__sync_add_and_fetch<span class="br0">&#40;</span><span class="sy0">&amp;</span>v<span class="sy0">-&gt;</span>counter<span class="sy0">,</span> i<span class="br0">&#41;</span> <span class="sy0">&lt;</span> <span class="nu0">0</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="co2">#endif</span></code></pre>

<p>Pretty straight forward isn&#8217;t it? It could be even more powerful and simpler if you don&#8217;t need precise compatibility with atomic.h. For example, atomic_add could easily return the result values:</p>

<pre class="lang-c"><code><span class="kw4">static</span> <span class="kw2">inline</span> <span class="kw4">int</span> atomic_add<span class="br0">&#40;</span> <span class="kw4">int</span> i<span class="sy0">,</span> atomic_t <span class="sy0">*</span>v <span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">return</span> __sync_add_and_fetch<span class="br0">&#40;</span><span class="sy0">&amp;</span>v<span class="sy0">-&gt;</span>counter<span class="sy0">,</span> i<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></code></pre>

<p>As a second example, consider a compare and swap operation, frequently used in lock-free algorithms. Once again, it&#8217;s trivially:</p>

<pre class="lang-c"><code><span class="coMULTI">/**<br />
&nbsp;* @brief compare and swap<br />
&nbsp;* @param v pointer of type atomic_t<br />
&nbsp;*<br />
&nbsp;* If the current value of @b v is @b oldval,<br />
&nbsp;* then write @b newval into @b v. Returns #TRUE if<br />
&nbsp;* the comparison is successful and @b newval was<br />
&nbsp;* written.<br />
&nbsp;*/</span><br />
<span class="kw4">static</span> <span class="kw2">inline</span> <span class="kw4">int</span> atomic_cas<span class="br0">&#40;</span> atomic_t <span class="sy0">*</span>v<span class="sy0">,</span> <span class="kw4">int</span> oldval<span class="sy0">,</span> <span class="kw4">int</span> newval <span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> __sync_bool_compare_and_swap<span class="br0">&#40;</span><span class="sy0">&amp;</span>v<span class="sy0">-&gt;</span>counter<span class="sy0">,</span> oldval<span class="sy0">,</span> newval<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></code></pre>

<p>Found this useful? Leave a comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://golubenco.org/2007/06/14/atomic-operations/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>
