View Issue Details
|ID||Project||Category||View Status||Date Submitted||Last Update|
|0018226||FPC||RTL||public||2010-12-15 19:58||2010-12-16 23:54|
|Reporter||Denis Philippov||Assigned To||Jonas Maebe|
|Status||resolved||Resolution||no change required|
|Summary||0018226: Socket operation in a threaded application doesn't work as expected|
|Description||I'am trying to create a multithreaded http client of a http (audio|video)streaming server. My goal to mesure streams bitrates. I got a synapse library and put a simple http client into thread object. I clear THTTPSend.Document each time then the HR_ReadCount status event occured, record size of the block, time and calculate the bitrate. |
Everything works well until I start 2 or more threads. I got 'Socket already connected' error on connect. To avoid this error I created new socket with THTTPSend.Sock.CreateSocket, THTTPSend.Sock.Disconnect. After this THTTPSend connects successfully, but reading from both connections stops with a 'connection time out' error.
|Steps To Reproduce||Create a thread object and put a simple socket reading example into it. Create an app that starts a two or more such threads. See how it works.|
|Tags||No tags attached.|
|Fixed in Revision|
Maybe the server simply doesn't accept (or limits) multiple connections from the same IP?
What is exactly a bug? And if so, why do you think it is FPC rather than synapse related?
No. Server software (getstream, DVB streaming server) doesn't contain such feature.
This is not a synapse bug, because I tried Synapse, Indy and plain fpsocket/ fpconnect/fprecv code with same result.
Please wait some time. I will prepare test project.
socktest2.tar.gz (2,568 bytes)
Your code never checks for EINTR. See "man select", "man connect" etc. All of them can return -1 and errno=ESysEINTR in case the operation has been interrupted for some reason (the chances of that happening increase a lot in multi-threaded programs).
Search for EINTR in e.g. http://svn.freepascal.org/svn/fpc/trunk/rtl/unix/sysutils.pp to see how you must handle such results. The sockets unit is a raw wrapper for the OS functionality, so any results that can returned by the OS versions of those functions can be returned by the sockets unit version.
||Also note that for operations in the sockets unit, you should check "socketerror" rather than errno (that one will always contain the "errno" result from the last sockets operation, regardless of any other operations executed afterwards): http://www.freepascal.org/docs-html/rtl/sockets/socketerror.html|
|2010-12-15 19:58||Denis Philippov||New Issue|
|2010-12-15 20:04||Marco van de Voort||Note Added: 0044239|
|2010-12-15 21:38||Denis Philippov||Note Added: 0044244|
|2010-12-16 00:07||Denis Philippov||File Added: socktest2.tar.gz|
|2010-12-16 23:48||Jonas Maebe||Status||new => resolved|
|2010-12-16 23:48||Jonas Maebe||Resolution||open => no change required|
|2010-12-16 23:48||Jonas Maebe||Assigned To||=> Jonas Maebe|
|2010-12-16 23:48||Jonas Maebe||Note Added: 0044277|
|2010-12-16 23:54||Jonas Maebe||Note Added: 0044280|