Alas it mostly shows how lacking the threading support in VCL is... The proper alternative to that snippet is rather heavy and complex if you only work with out of the box functionality...
procedure TADO_WE_Connection.SetConnectionExecuting; begin // only one process can set executing at the given moment // until that process has done executing next process cannot even start executing. { TODO -oNick : This looks very suspicious } WaitForSingleObject(hLock, INFINITE); try while FbExecuting do sleep(1); FbExecuting := True; finally ReleaseMutex(hLock); end; end;
Nick Hodges that code is probably used to wait for an event which is triggered within the current thread context. Processmessages is called to let events fire and Sleep is called to not consume too much CPU altough 10mS is a little bit short in that context. The "conn.bExecutin let me think it is related to communication whcih is probably interrupt driven and only triggers an event when a complete line / block : message is received. This code is perfectly correct in a cooperative multi-tasking environment.
That loop with sleep(1) is an alternative to a triggerable event, 1 is a bit low to minimize CPU usage, but if the execution is short enough, it could have been picked to minimize latency. A triggerable event is preferable for long waits, but used to have significant overhead. The mutex is used to protect the Boolean which is used as signaling flag, which is okay, the Boolean being byte-sized, assignments to it are atomic.
So while it's possible to write a more academically correct version, that wouldn't really make the code look simpler ;-)
I fear that it could be either. And the only way to find out is to further investigate the code.
I am also working with "interesting" multithreaded code. Specifically, to perform a sequence of tasks a thread pool is created, then each thread is activated once the previous thread terminates. Almost all of the tasks depend on the previous task(s) finishing successfully. It is very odd.
Threading for hackers :)
ReplyDeleteAlas it mostly shows how lacking the threading support in VCL is... The proper alternative to that snippet is rather heavy and complex if you only work with out of the box functionality...
ReplyDeleteconn.bExecuting... I just find that funny on several levels.
ReplyDeleteI confess I'm not 100% clear on what is going on.....
ReplyDeleteNot that complicated. You just create a mailbox and send let the threads send telegrams to the main thread for it to pick up the mail.
ReplyDeleteThe plot thickens!
ReplyDeleteprocedure TADO_WE_Connection.SetConnectionExecuting;
begin
// only one process can set executing at the given moment
// until that process has done executing next process cannot even start executing.
{ TODO -oNick : This looks very suspicious }
WaitForSingleObject(hLock, INFINITE);
try
while FbExecuting do sleep(1);
FbExecuting := True;
finally
ReleaseMutex(hLock);
end;
end;
Nice! Can I get the author's autograph? ;)
ReplyDeleteNick Hodges that code is probably used to wait for an event which is triggered within the current thread context. Processmessages is called to let events fire and Sleep is called to not consume too much CPU altough 10mS is a little bit short in that context. The "conn.bExecutin let me think it is related to communication whcih is probably interrupt driven and only triggers an event when a complete line / block : message is received. This code is perfectly correct in a cooperative multi-tasking environment.
ReplyDeleteThat loop with sleep(1) is an alternative to a triggerable event, 1 is a bit low to minimize CPU usage, but if the execution is short enough, it could have been picked to minimize latency. A triggerable event is preferable for long waits, but used to have significant overhead. The mutex is used to protect the Boolean which is used as signaling flag, which is okay, the Boolean being byte-sized, assignments to it are atomic.
ReplyDeleteSo while it's possible to write a more academically correct version, that wouldn't really make the code look simpler ;-)
I fear that it could be either. And the only way to find out is to further investigate the code.
ReplyDeleteI am also working with "interesting" multithreaded code. Specifically, to perform a sequence of tasks a thread pool is created, then each thread is activated once the previous thread terminates. Almost all of the tasks depend on the previous task(s) finishing successfully. It is very odd.
Hey... I was on codeine when I wrote that. ;).
ReplyDeleteAaaaaaargh!
ReplyDeleteWell, why not? Just waiting for a message, with some rather odd code!
ReplyDeleteWhenever I see bExecuting or FbExecuting or any other hungarian notation in Delphi code I reach for my gun
ReplyDeleteI wrote an article about that subject: http://francois-piette.blogspot.be/2013/11/what-is-processmessages.html
ReplyDelete