This project has moved. For the latest updates, please go here.


TIdTCPServer.Active deadlock on Android


When running on Android, setting TIdTCPServer.Active to False deadlocks, even when no clients are connected.
Closed Apr 6 at 1:38 AM by gambit47


gambit47 wrote May 30, 2014 at 2:35 AM

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().

wrote Apr 6 at 1:38 AM