From: aminer on

Hello,

I have been testing all the night , and i have discovered a
problem, look at the following in the execute() method inside
my Thread Pool Engine:

--------------------------------------------------------------------------

function TThreadPool.execute(func:TMyProc;const Context: Pointer):
Boolean;

var
local_balance,local_count:integer;
params: PParams;
p:pointer;

begin
new(params);
setlength(params^,1);
params^[0].proc:=func;
params^[0].data:=context;

local_balance:=LockedIncLong(balance1) mod FThreadCount;
1-local_count:=Queues[local_balance].count;
2-while not Queues[local_balance].push(tobject(params^)) do;
3-if local_count=0 then events[local_balance].setevent;
p:=params;
dispose(p);

end;

------------------------------------------


If local_count is not zero and between 1-3 the worker thread
have poped all the objects from the queue and it enters in a
waiting state, the event will not be signaled from the producer ,
and there is a possibility of a 'deadlock'.


So i have changed it to the following, to avoid the deadlock:

--------------------------------------------------------------------------

function TThreadPool.execute(func:TMyProc;const Context: Pointer):
Boolean;

var
local_balance,local_count:integer;
params: PParams;
p:pointer;

begin
new(params);
setlength(params^,1);
params^[0].proc:=func;
params^[0].data:=context;

local_balance:=LockedIncLong(balance1) mod FThreadCount;
//local_count:=Queues[local_balance].count;
while not Queues[local_balance].push(tobject(params^)) do;
//if local_count=0 then events[local_balance].setevent;
events[local_balance].setevent;
p:=params;
dispose(p);

end;

------------------------------------------



You can download my Thread Pool Engine ,and the other modules
that use it, from:

http://pages.videotron.com/aminer/


Sincerely,
Amine Moulay Ramdane.


From: aminer on

Hello,

Look at the new code:

1- while not Queues[local_balance].push(tobject(params^)) do;
2- events[local_balance].setevent;


Now if between 1-2 the worker thread have poped all the objects
from the queue and it enters in a waiting state, the event will
be signaled by the producer - so no problem -

and

If the consumer was in a waiting state , the event will be signaled
by the consumer - so no problem -

and

If the consumer was doing its job poping and exxecuting, the event
will be signaled - so no problem here -


And in all those cases, there will be NO deadlock.



Sincerely,
Amine Moulay Ramdane.

..


On Apr 22, 12:13 am, aminer <ami...(a)videotron.ca> wrote:
> Hello,
>
> I have been testing all the night , and i have discovered a
> problem, look at the following in the execute() method inside
> my Thread Pool Engine:
>
> --------------------------------------------------------------------------
>
> function TThreadPool.execute(func:TMyProc;const Context: Pointer):
> Boolean;
>
> var
> local_balance,local_count:integer;
> params:  PParams;
> p:pointer;
>
> begin
> new(params);
> setlength(params^,1);
> params^[0].proc:=func;
> params^[0].data:=context;
>
> local_balance:=LockedIncLong(balance1) mod FThreadCount;
> 1-local_count:=Queues[local_balance].count;
> 2-while not Queues[local_balance].push(tobject(params^))  do;
> 3-if local_count=0 then events[local_balance].setevent;
> p:=params;
> dispose(p);
>
> end;
>
> ------------------------------------------
>
> If local_count is not zero  and between 1-3 the worker thread
> have poped all the objects from the queue and it enters in a
> waiting state,  the event will not be signaled from the producer ,
> and  there is a possibility of a 'deadlock'.
>
> So i have changed it to the following, to avoid the deadlock:
>
> --------------------------------------------------------------------------
>
> function TThreadPool.execute(func:TMyProc;const Context: Pointer):
> Boolean;
>
> var
> local_balance,local_count:integer;
> params:  PParams;
> p:pointer;
>
> begin
> new(params);
> setlength(params^,1);
> params^[0].proc:=func;
> params^[0].data:=context;
>
> local_balance:=LockedIncLong(balance1) mod FThreadCount;
> //local_count:=Queues[local_balance].count;
> while not Queues[local_balance].push(tobject(params^))  do;
> //if local_count=0 then events[local_balance].setevent;
> events[local_balance].setevent;
> p:=params;
> dispose(p);
>
> end;
>
> ------------------------------------------
>
> You can download my Thread Pool Engine ,and the other modules
> that use it, from:
>
> http://pages.videotron.com/aminer/
>
> Sincerely,
> Amine Moulay Ramdane.