#1 2021-02-06 16:12:29

mpv
Member
From: Ukraine
Registered: 2012-03-24
Posts: 1,564
Website

Termination of blocking operations in SynCrtSock

I use a TCrtSocket to implement a Redis protocol. Everything works fine ( we got up to 100 000 simple operations (GET, INCR) per second on Linux and up to 30 000 on Windows)
The only problem is terminating a blocking operation (  SockInRead / readln(SockIn^) ) while program needs to be closed.

On Linux we terminate a deamon by sending a signal (INT / TSTP /  HUP). In this case kernel unblock a blocking operations for most calls.

recv call is return EINTR when interrupted by signal. But TCrtSocket ignore EINTR here - https://github.com/synopse/mORMot/blob/ … .pas#L4831

Is any practical reason for this? If not - I suggest to remove a (err<>WSAEINTR) check, at last for Unix (don't know what is a semantic of  EINTR on Windows - there is no signals there)

And the same code is in mROMot2

Offline

#2 2021-02-06 23:24:27

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,375
Website

Re: Termination of blocking operations in SynCrtSock

You are right: WSAEINTR doesn't mean the same then EINTR.

On Windows, it means that it stopped blocking by a legacy https://docs.microsoft.com/en-us/window … ockingcall
This may be a legacy from very old time on Windows... from Synapse library perhaps.
I guess this won't be needed any more.

On POSIX, EINTR really means that a Signal was received. We should stop and return the call here for sure.

So it sounds fair to remove WSAEINTR check - for both platforms.
Check https://synopse.info/fossil/info/7af21f8c96
(also for mORMot 2)

Offline

#3 2021-02-07 14:44:54

mpv
Member
From: Ukraine
Registered: 2012-03-24
Posts: 1,564
Website

Re: Termination of blocking operations in SynCrtSock

Thanks! Now blocking operations in main thread are terminated successfully.
The next step is to terminate it in workers. Threads created by program do nor receive process signals if we intercept it inside main thread, so we need some aditional step.
I create a merge request #378 what allow direct access to the worker threads in the thread pool.
Not shure my code to terminate a blocking operations in workers is good (IMHO it's ugly), so I do not tries to put in into mORMot. But it works for me

// send an INT signal to all workers to break a possible blocking opeartions
 for i := 0 to myHttpServer.ThreadPool.WorkerThreadsCount - 1 do
   pthread_kill(myHttpServer.ThreadPool.WorkerThreads[i].ThreadID, SIGINT); 

BTW (for mORMot2) - I propose to rename a TSynThreadPoolSubThread -> TSynWorkerThread and correspondent variable names.
Current code:

TSynThreadPool = class
  protected
    fSubThread: array of TSynThreadPoolSubThread;
    fSubThreadCount: integer

code after renaming

TSynThreadPool = class
  protected
    fWorkerThreads: array of TSynWorkerThread;
    fWorkerThreadsCount: integer

Name "SubThread" is always be confusing to me. "Sub" of what?  The main class (threadPool) is not a thread.
And "workers" is a common name for such pattern.

Last edited by mpv (2021-02-07 14:45:42)

Offline

Board footer

Powered by FluxBB