<?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>Fabio Falcinelli &#187; Deadlock</title>
	<atom:link href="http://www.fabiofalcinelli.it/tag/deadlock/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.fabiofalcinelli.it</link>
	<description>A mix of code and photos...</description>
	<lastBuildDate>Sat, 29 May 2010 12:16:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Java &#8211; Esecuzione comandi su CLI parte II</title>
		<link>http://www.fabiofalcinelli.it/2009/02/java-esecuzione-comandi-su-cli-part-ii/</link>
		<comments>http://www.fabiofalcinelli.it/2009/02/java-esecuzione-comandi-su-cli-part-ii/#comments</comments>
		<pubDate>Wed, 04 Feb 2009 20:24:08 +0000</pubDate>
		<dc:creator>Fabio</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[Deadlock]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[UNIX]]></category>

		<guid isPermaLink="false">http://fabiofalcinelli.netsons.org/?p=132</guid>
		<description><![CDATA[Se vi ricordate di un pezzo di codice scritto da me e che funzionava particolarmente bene per invocare comandi su UNIX&#8230; Beh&#8230; Scordatevelo! O meglio, dovrete fare qualche piccola modifica. Il codice in questione sembra, infatti, causare un piccolo problema chiamato deadlock. La cosa non si presenta sempre, ma dipende fortemente dalla quantità di output [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Se vi ricordate di un <a title="Java - Esecuzione comandi su CLI" href="http://fabiofalcinelli.netsons.org/2009/01/java-esecuzione-comandi-su-cli/" target="_blank">pezzo di codice scritto da me</a> e che funzionava particolarmente bene per invocare comandi su UNIX&#8230; Beh&#8230; Scordatevelo! O meglio, dovrete fare qualche piccola modifica.</p>
<p style="text-align: justify;">Il codice in questione sembra, infatti, causare un piccolo problema chiamato <em>deadlock</em>.</p>
<p style="text-align: justify;">La cosa non si presenta sempre, ma dipende fortemente dalla quantità di output che genera il comando e da come il sistema operativo gestisce il buffering della system call &#8220;write&#8221;. Lanciando <em>truss</em> da dentro al codice java, infatti, notavo che l&#8217;esecuzione delle system call si bloccava in attesa:</p>
<div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ioctl<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1</span>, TCGETA, 0xFFBEDF34<span style="color: #7a0874; font-weight: bold;">&#41;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Err<span style="color: #666666; font-style: italic;">#22 EINVAL</span><br />
fstat64<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1</span>, 0xFFBEDFA8<span style="color: #7a0874; font-weight: bold;">&#41;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = <span style="color: #000000;">0</span><br />
brk<span style="color: #7a0874; font-weight: bold;">&#40;</span>0x00068A70<span style="color: #7a0874; font-weight: bold;">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = <span style="color: #000000;">0</span><br />
brk<span style="color: #7a0874; font-weight: bold;">&#40;</span>0x0006AA70<span style="color: #7a0874; font-weight: bold;">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = <span style="color: #000000;">0</span><br />
<span style="color: #c20cb9; font-weight: bold;">write</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1</span>, <span style="color: #ff0000;">&quot; D A T A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;</span>.., <span style="color: #000000;">5120</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>&nbsp; &nbsp; = <span style="color: #000000;">5120</span><br />
<span style="color: #c20cb9; font-weight: bold;">write</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1</span>, <span style="color: #ff0000;">&quot; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; * - &gt; *&quot;</span>.., <span style="color: #000000;">5120</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>&nbsp; &nbsp; = <span style="color: #000000;">5120</span><br />
llseek<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">0</span>, <span style="color: #000000;">0</span>, SEEK_CUR<span style="color: #7a0874; font-weight: bold;">&#41;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Err<span style="color: #666666; font-style: italic;">#29 ESPIPE</span><br />
<span style="color: #c20cb9; font-weight: bold;">write</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1</span>, <span style="color: #ff0000;">&quot; * - &gt; * * * * * &nbsp; &nbsp; &nbsp; &nbsp;&quot;</span>.., <span style="color: #000000;">635</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>sleeping...<span style="color: #7a0874; font-weight: bold;">&#41;</span></div></div>
<p style="text-align: justify;">Non è stato facilissimo arrivare alla causa, il metodo è infatti molto semplice, ma adesso che ho identificato il problema l&#8217;errore appare quasi evidente. Il problema risiede infatti nel canale di <em>standard error </em>letto prima dello <em>standard output</em>:</p>
<ol style="text-align: justify;">
<li>Prima di poter leggere lo standard error è necessario che il processo che esegue il comando termini, e non è detto che vi siano errori;</li>
<li>Prima di poter avere tutto l&#8217;output disponibile c&#8217;è bisogno di qualcuno che consumi i dati nel buffer, ma quel qualcuno è in attesa sullo standard error;</li>
<li>Deadlock!</li>
</ol>
<p style="text-align: justify;">Sinceramente, questa spiegazione, seppur sensata non mi convince ancora appieno e appena avrò più tempo analizzerò meglio i trace delle system call, nonostante ciò riporto di seguito la versione del metodo che risolve il problema.</p>
<div class="codecolorer-container java twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399;">String</span> execCommand<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> cmd<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">IOException</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #003399;">String</span> result <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #003399;">String</span> temp <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #003399;">BufferedReader</span> stdout <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #003399;">BufferedReader</span> stderr <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #003399;">Process</span> proc <span style="color: #339933;">=</span> <span style="color: #003399;">Runtime</span>.<span style="color: #006633;">getRuntime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">exec</span><span style="color: #009900;">&#40;</span>cmd<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;">/*consume the output*/</span><br />
&nbsp; &nbsp;stdout <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">BufferedReader</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">InputStreamReader</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;proc.<span style="color: #006633;">getInputStream</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;temp <span style="color: #339933;">=</span> stdout.<span style="color: #006633;">readLine</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">while</span><span style="color: #009900;">&#40;</span>temp<span style="color: #339933;">!=</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>result<span style="color: #339933;">==</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;result <span style="color: #339933;">=</span> temp<span style="color: #339933;">+</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;result <span style="color: #339933;">+=</span> temp<span style="color: #339933;">+</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; temp <span style="color: #339933;">=</span> stdout.<span style="color: #006633;">readLine</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp;stdout.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;">/*check if errors occurred*/</span><br />
&nbsp; &nbsp;stderr <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">BufferedReader</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">InputStreamReader</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; proc.<span style="color: #006633;">getErrorStream</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;temp <span style="color: #339933;">=</span> stderr.<span style="color: #006633;">readLine</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>temp<span style="color: #339933;">!=</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; result <span style="color: #339933;">=</span> temp<span style="color: #339933;">+</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; temp <span style="color: #339933;">=</span> stderr.<span style="color: #006633;">readLine</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">while</span><span style="color: #009900;">&#40;</span>temp<span style="color: #339933;">!=</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;result <span style="color: #339933;">+=</span> temp<span style="color: #339933;">+</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;temp <span style="color: #339933;">=</span> stderr.<span style="color: #006633;">readLine</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; stderr.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IOException</span><span style="color: #009900;">&#40;</span>result<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp;stderr.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;">/*if no exceptions occurred then proceed to return the output*/</span><br />
&nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">return</span> result<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p style="text-align: justify;">Questo è quanto, il metodo main d&#8217;esempio del post precedente però è ancora valido :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fabiofalcinelli.it/2009/02/java-esecuzione-comandi-su-cli-part-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
