Board index » delphi » Answered my own question.....

Answered my own question.....


2004-07-17 08:31:26 PM
delphi262
TQueue is not inherently threadsafe, so still requires a lock and your
timeout thread idea......
Dean
 
 

Re:Answered my own question.....

"Dean" <dean@[spambuster]weany.com>writes
Quote
TQueue is not inherently threadsafe, so still requires a lock and your
timeout thread idea......
Safe, waitable, version of TobjectQueue with timeouts below. Yes, it does
use a CS for locking, but only for the time spent actually dequeueing
objects. Your timeout thread could wait on it for any RR object. The RR
could contain a stream, buffer, whatever. it is also useful if the RR object
has a parameterless 'replyToSender(result:string)' method that uses internal
private data for replying, eg. for replying to a main-thread form, an RR
subclass could contain the handle & message number for a postMessage & the
overridden 'replyToSender' could store away the result string in a private
field & do the actual postMessaging. This makes it easy for any of the
threads to send back a buffer from anywhere, eg.
var myRR:TsomeRRclass;
begin
repeat
myRequestQueue.pop(@myRR,INFINITE);
try
something;
myRR.replyToSender('')
except
on e:exception do
myRR.replyToSender(e.message)
end;
until terminated;
end;
That way, the threads do not need to know anything about the sender or how
to reply. They just call the method of the RR & it is done, from anywhere.
The originators get RRs back & can check the result string for ''.
Rgds,
Martin
pObject=^Tobject;
TsemaphoreMailbox=class(TobjectQueue)
private
countSema:Thandle;
access:TcriticalSection;
public
property semaHandle:Thandle read countSema;
constructor create;
procedure push(aObject:Tobject);
function pop(pResObject:pObject;timeout:integer):boolean;
destructor destroy; override;
end;
..
..
{ TsemaphoreMailbox }
constructor TsemaphoreMailbox.create;
begin
inherited create;
access:=TcriticalSection.create;
countSema:=createSemaphore(nil,0,maxInt,nil);
end;
destructor TsemaphoreMailbox.destroy;
begin
access.free;
closeHandle(countSema);
inherited;
end;
function TsemaphoreMailbox.pop(pResObject: pObject;
timeout: integer): boolean;
begin
result:=(WAIT_OBJECT_0=waitForSingleObject(countSema,timeout));
if result then
begin
access.acquire;
pResObject^:=inherited pop;
access.release;
end;
end;
procedure TsemaphoreMailbox.push(aObject: Tobject);
begin
access.acquire;
inherited push(aObject);
access.release;
releaseSemaphore(countSema,1,nil);
end;
 

Re:Answered my own question.....

Quote
objects. Your timeout thread could wait on it for any RR object. The RR
could contain a stream, buffer, whatever. it is also useful if the RR
object
has a parameterless 'replyToSender(result:string)' method that uses
internal
private data for replying, eg. for replying to a main-thread form, an RR
Semms I thing that 'replyToSender(result:string)' is parameterless!
Oops!
Oh well, put it down to lack of beer.
Rgds,
Martin