<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Passing Curiosity: Posts tagged deadlock</title>
    <link href="https://passingcuriosity.com/tags/deadlock/deadlock.xml" rel="self" />
    <link href="https://passingcuriosity.com" />
    <id>https://passingcuriosity.com/tags/deadlock/deadlock.xml</id>
    <author>
        <name>Thomas Sutton</name>
        
        <email>me@thomas-sutton.id.au</email>
        
    </author>
    <updated>2015-03-04T00:00:00Z</updated>
    <entry>
    <title>Reading from processes safely in Haskell</title>
    <link href="https://passingcuriosity.com/2015/haskell-reading-process-safe-deadlock/" />
    <id>https://passingcuriosity.com/2015/haskell-reading-process-safe-deadlock/</id>
    <published>2015-03-04T00:00:00Z</published>
    <updated>2015-03-04T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>Quite a bit of my work lately has been implementing HTTP interfaces to existing
systems. In a few cases this required invoking existing command-line tools and
parsing their output. The naive approach to invoking a <a href="https://hackage.haskell.org/package/process">process</a> in Haskell
and reading its output goes something like this:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">System.Exit</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">System.Process</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="ot">main ::</span> <span class="dt">IO</span> ()</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> p <span class="ot">=</span> (shell <span class="st">&quot;cat /usr/share/dict/words&quot;</span>)</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>            { std_in  <span class="ot">=</span> <span class="dt">Inherit</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>            , std_out <span class="ot">=</span> <span class="dt">CreatePipe</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>            , std_err <span class="ot">=</span> <span class="dt">Inherit</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>            }</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>    (<span class="dt">Nothing</span>, <span class="dt">Just</span> out, <span class="dt">Nothing</span>, ph) <span class="ot">&lt;-</span> createProcess p</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>    ec <span class="ot">&lt;-</span> waitForProcess ph</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">case</span> ph <span class="kw">of</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>        <span class="dt">ExitSuccess</span>   <span class="ot">-&gt;</span> hGetContents out <span class="op">&gt;&gt;=</span> <span class="fu">print</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>        <span class="dt">ExitFailure</span> _ <span class="ot">-&gt;</span> <span class="fu">error</span> <span class="st">&quot;Bad things happened. :-(&quot;</span></span></code></pre></div>
<p>There is a potential problem in this code: we wait until the process has
terminated before reading the <code>Handle</code> allowing its output to accumulate in the
pipe buffer managed by the operating system in the mean time. This buffer has
a fixed size on most systems (this is a good thing!); when it fills up, the
writing process will go to sleep until the reader has consumed some data and
freed some buffer space to hold the next write. Alas, the reader (the Haskell
code above) is sleeping, waiting for the writer to terminate. The reader is
sleeping, waiting for the writer to terminate; and the writer is sleeping,
waiting for the reader to read. This is a <a href="https://en.wikipedia.org/wiki/Deadlock">deadlock</a>!</p>
<p>The solution is to do the Right Thing (tm) and take care of any buffering
behaviour we want ourselves. Thankfully this is pretty straightforward and it’s
the sort of code you generally only need to write once. The very simplest case
– reading from a process with a single output <code>Handle</code> – looks like this:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">gatherOutput ::</span> <span class="dt">ProcessHandle</span> <span class="ot">-&gt;</span> <span class="dt">Handle</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> (<span class="dt">ExitCode</span>, <span class="dt">ByteString</span>)</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>gatherOutput ph h <span class="ot">=</span> work <span class="fu">mempty</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    work acc <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>        <span class="co">-- Read any outstanding input.</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>        bs <span class="ot">&lt;-</span> BS.hGetNonBlocking h (<span class="dv">64</span> <span class="op">*</span> <span class="dv">1024</span>)</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> acc' <span class="ot">=</span> acc <span class="op">&lt;&gt;</span> bs</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>        <span class="co">-- Check on the process.</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>        s <span class="ot">&lt;-</span> getProcessExitCode ph</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>        <span class="co">-- Exit or loop.</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> s <span class="kw">of</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>            <span class="dt">Nothing</span> <span class="ot">-&gt;</span> work acc'</span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>            <span class="dt">Just</span> ec <span class="ot">-&gt;</span> <span class="kw">do</span></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a>                <span class="co">-- Get any last bit written between the read and the status</span></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a>                <span class="co">-- check.</span></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a>                <span class="fu">last</span> <span class="ot">&lt;-</span> BS.hGetContents h</span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a>                <span class="fu">return</span> (ec, acc' <span class="op">&lt;&gt;</span> <span class="fu">last</span>)</span></code></pre></div>
<p>This is essentially a loop which reads some input from the <code>Handle</code> (possibly
an empty string), checks to see if the process has terminated, and either
returns the accumulated input or loops again. Extending this to gather the
output of two handles (like <code>stderr</code> and <code>stdout</code>) is relatively
straightforward.</p>]]></summary>
</entry>

</feed>
