jumaris / indyproject

Automatically exported from code.google.com/p/indyproject
0 stars 0 forks source link

TIdTCPServer.Active deadlock on Android #292

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
When running on Android, setting TIdTCPServer.Active to False deadlocks, even 
when no clients are connected.

Original issue reported on code.google.com by gambit47 on 28 May 2014 at 8:22

GoogleCodeExporter commented 9 years ago
Found the problem. ARC bites again :(

In TIdListenerThread.Run() before a client is accepted, TIdTCPServer retrieves 
a new Yarn from its Scheduler. Using the default Scheduler, a new thread is 
created at that time, but in a suspended state. The thread is resumed when a 
client connects and a TIdContext task is assigned to the thread. But when there 
is no client connected yet, the thread remains suspended.

During server shutdown, TIdTCPServer asks the Scheduler to terminate its active 
Yarns. However, TIdSchedulerOfThread.TerminateYarn() was using FreeAndNil() to 
free a Yarn that does not have a running thread, and that does not work under 
ARC because the Yarn is referenced by its thread and vice versa, so the Yarn's 
refcount was not falling to 0 and thus the Yarn was not being freed (and more 
importantly, its thread was not being resumed and terminated correctly). So the 
Yarn was not getting removed from the Scheduler's list of active Yarns, and 
TIdTCPServer ended up stuck in a loop waiting for active Yarns to clear out but 
they never did. Hense the shutdown deadlock.

This does not happen on desktop systems, where FreeAndNil() frees the Yarn 
immediately, so everything gets cleared out as expected.

Fixed in rev 5140 by replacing FreeAndNil() with IdDisposeAndNil() in 
TIdSchedulerOfThread.TerminateYarn().

Original comment by gambit47 on 30 May 2014 at 2:34