Re: [Lazarus] How to PostMessage to object?

2011-06-10 Thread Michael Schnell

On 06/09/2011 08:00 PM, Krzysztof wrote:
So, I wrote TMyHTTPClient which is some kind of layer for synapse http 
client 

AsyncPro is a good example for something like this:

An instance of an APRO Object (that handles either an asynchronous or a 
TCP/IP-Socket based bidirectional stream) internally creates threads 
that are assigned to the blocking in and out API functions of the OS.


Mechanisms like that we have been discussing here, are used to make the 
interface of the object completely un-threaded (and with that 
thread-safe). There are event properties, and the functions defined 
there are called in the context of the main thread when an internal 
worker thread schedules the event. Data is provided to theses event 
handlers in a thread-safe manner.


Multiple requests in this forum and elsewhere suggest that Lazarus would 
benefit a lot from an Async-Pro port or work-alike, being part of the 
packet.


Maybe you can do your project in a way that in a versatile way 
implements the core of this: a class that creates internal in and 
out threads and provides hooks for attaching a blocking interface of 
any kind of byte-stream to same.


The now bug-free Application.QueueAsyncCall() should be the perfect 
thread-transfer-mechanism.


Only downside: AFAIK, right now it is not possible to create a Lazarus 
Application that has no GUI binding and provides a working 
Application.QueueAsyncCall() and TTimers that would allow you to easily 
react on timeouts in the communication you are monitoring. So you 
supposedly need to do a GTK2, QT, or Windows application.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Michael Schnell

On 06/08/2011 05:28 PM, Krzysztof wrote:
Hm, I forgot about Application.QueueAsyncCall. And this can be safely 
call from thread without TThread.Synchronize() ? 
This is exactly what Application.QueueAsyncCall() (and what the 
Delphi-Worlkalike TThread.Queue() ) does-
Because I don't want use Synchronize() in any part of thread code. So 
this is correct code? :


procedure TMyThread.Execute;
begin
  // some code here
  Application.QueueAsyncCall(@SomeObj.TestMethod, PtrInt(NewStr('Some 
value')));

  // some code here
end;


here is the code I tested (the thread class offers a proptery 
OnACall_Parameters as a hook for attaching a Main-Thread handling 
procedure):


Type
  TAsyncData = record
S: String;
D: Integer;
  end;
  TPAsyncData = ^TAsyncData;

  TAsyncCall_Parameters = procedure(S: String; D: Integer) of object;

  public
 OnACall_Parameters: TAsyncCall_Parameters;

var
   PAsyncData: TPAsyncData;

begin
  new(PAsyncData);
  PAsyncData^.d:=Global_I;
  PAsyncData^.S:= 'T E S T';
  Application.QueueAsyncCall(@DACall_Parameters, PtrInt(PAsyncData));
end;


procedure TWorkerThread.DACall_Parameters(Data: PtrInt);
var
  PAsyncData: TPAsyncData;
begin
  PAsyncData:=TPAsyncData(Data);
  if assigned(OnACall_Parameters) then 
OnACall_Parameters(PAsyncData^.S, PAsyncData^.D);

  Dispose(PAsyncData);
end;

-Michael
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Michael Schnell

On 06/08/2011 05:39 PM, Henry Vermaak wrote:

There is no chance for deadlock with main thread calling this from
inside another thread?



You have to protect it with a critical section (if you have more than 
one thread calling QueueAsyncCall).


A critical section likely will kill the thread latency, so this should 
be avoided


You can fire the same main thread event from many threads. the LCL will 
queue them and the main thread will handle them one after the other.


If designed properly, a deadlock can't happen. You need to take care 
that the data is allocated before sending it to the main thread and the 
main thread deallocates it (see example code).


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Henry Vermaak

On 09/06/11 09:50, Michael Schnell wrote:

On 06/08/2011 05:39 PM, Henry Vermaak wrote:

There is no chance for deadlock with main thread calling this from
inside another thread?



You have to protect it with a critical section (if you have more than
one thread calling QueueAsyncCall).


A critical section likely will kill the thread latency, so this should
be avoided


You will corrupt the linked list that QueueAsyncCall uses when you call 
it from multiple threads, so you _must_ protect it.



You can fire the same main thread event from many threads. the LCL will
queue them and the main thread will handle them one after the other.


It doesn't matter if it's the same event or not, all events are stored 
in a list by QueueAsyncCall.  I don't know why they didn't use a 
thread-safe queue for this.


Henry

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Mattias Gaertner
 
 

 Michael Schnell mschn...@lumino.de hat am 9. Juni 2011 um 10:50 geschrieben:

  On 06/08/2011 05:39 PM, Henry Vermaak wrote:
   There is no chance for deadlock with main thread calling this from
   inside another thread?
  
  
   You have to protect it with a critical section (if you have more than
   one thread calling QueueAsyncCall).
 
  A critical section likely will kill the thread latency, so this should
  be avoided 
How many calls per second do you want to execute via the main thread?

 QueueAsyncCall is *not* thread safe.  If QueueAsyncCall should be made thread
safe, then TApplication must be extended to use a critical section for it (or
some lock-free queue, but since we are talking about the GUI thread, latency is
already so bad, that this makes no difference).
 
Afaik all PostMessages implementations use a critical section. So you don't need
to do that yourself.
 
 
 [...]

 Mattias--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Michael Schnell

On 06/09/2011 10:58 AM, Henry Vermaak wrote:
You will corrupt the linked list that QueueAsyncCall() uses when you 
call it from multiple threads, so you _must_ protect it.
As QueueAsyncCall is specified exactly for this use, it needs to take 
care of this issue internally. Otherwise it obviously is buggy. I trust 
that the LCL developers did a decent job.


(The list access needs to be protected even with a single worker thread, 
as the main thread removes elements in a concurrent access anyway.)


-Michael


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Michael Schnell

On 06/09/2011 11:15 AM, Mattias Gaertner wrote:
QueueAsyncCall is *not* thread safe. 
If this is ture, I would call it a bug, as QueueAsyncCall obviously is 
designed to be used by threads.


but since we are talking about the GUI thread, latency is already so 
bad, that this makes no difference).


We are not. The purpose of QueueAsyncCall is to be used in a worker 
Thread. The delay introduced by the GUI thread that in some remote 
future is supposed to execute the queued task (e.g. display a progress 
bar showing how far the worker thread has gotten with its work) is not 
relevant.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Mattias Gaertner
 
 

 Michael Schnell mschn...@lumino.de hat am 9. Juni 2011 um 11:46 geschrieben:

  On 06/09/2011 10:58 AM, Henry Vermaak wrote:
   You will corrupt the linked list that QueueAsyncCall() uses when you
   call it from multiple threads, so you _must_ protect it.
  As QueueAsyncCall is specified exactly for this use, it needs to take
  care of this issue internally. Otherwise it obviously is buggy. I trust
  that the LCL developers did a decent job. 
The only specification I found for TApplication.QueueAsyncCall is the fpdoc
entry:
Insert a given asynchronous call into the queue
 
Why do you think it is thread safe?
 
  
  
  (The list access needs to be protected even with a single worker thread,
  as the main thread removes elements in a concurrent access anyway.)

 Mattias--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Michael Schnell

On 06/09/2011 12:01 PM, Mattias Gaertner wrote:


Why do you think it is thread safe?


I just trusted that it would be properly designed.

Looking at the code I found that it in fact seems to be buggy.

The linked list is modified both by the (even single) Worker Thread when 
inserting an element as by the main (GUI) thread when removing one 
without protection by a semaphore.


(Without decent analysis) I don't believe that there is no chance of 
hazard.


-Michael
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Henry Vermaak

On 08/06/11 16:39, Henry Vermaak wrote:

On 08/06/11 16:28, Krzysztof wrote:

Hm, I forgot about Application.QueueAsyncCall. And this can be safely
call from thread without TThread.Synchronize() ? Because I don't want
use Synchronize() in any part of thread code. So this is correct code? :

procedure TMyThread.Execute;
begin
// some code here
Application.QueueAsyncCall(@SomeObj.TestMethod, PtrInt(NewStr('Some
value')));
// some code here
end;

There is no chance for deadlock with main thread calling this from
inside another thread?


You have to protect it with a critical section (if you have more than
one thread calling QueueAsyncCall).


This will not even solve the problem, since the ProcessAsyncCallQueue 
and RemoveAsyncCalls also need to be protected.  Just use PostMessage 
for thread communication.


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Henry Vermaak

On 09/06/11 11:01, Mattias Gaertner wrote:



Michael Schnell mschn...@lumino.de hat am 9. Juni 2011 um 11:46
geschrieben:

  On 06/09/2011 10:58 AM, Henry Vermaak wrote:
   You will corrupt the linked list that QueueAsyncCall() uses when you
   call it from multiple threads, so you _must_ protect it.
  As QueueAsyncCall is specified exactly for this use, it needs to take
  care of this issue internally. Otherwise it obviously is buggy. I trust
  that the LCL developers did a decent job.

The only specification I found for TApplication.QueueAsyncCall is the
fpdoc entry:

Insert a given asynchronous call into the queue

Why do you think it is thread safe?


Do you propose that QueueAsyncCall throws an exception if it's used from 
outside the main thread?  Otherwise adding a critical section to all the 
async queue methods is in order.


Henry

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Michael Schnell

On 06/09/2011 12:12 PM, Henry Vermaak wrote:


Do you propose that QueueAsyncCall throws an exception if it's used 
from outside the main thread? 
The purpose of QueueAsyncCall() is to use it in worker threads to notify 
the main thread of something that happens in the thread (without the 
worker thread needing to wait that the main thread was able to handle 
the event). But it's not forbidden to call QueueAsyncCall() in the main 
thread.
Otherwise adding a critical section to all the async queue methods is 
in order.


IMOH protecting a call to QueueAsyncCall() (in user code or IMHO 
better in the LCL itself) by a semaphore should not harm anyway in most 
cases, as there would be no waiting on anything else in that critical 
section. If you assign different priorities to the threads there of 
course is the usual problem of priority inversion.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Henry Vermaak

On 09/06/11 11:29, Michael Schnell wrote:

On 06/09/2011 12:12 PM, Henry Vermaak wrote:


Do you propose that QueueAsyncCall throws an exception if it's used
from outside the main thread?

The purpose of QueueAsyncCall() is to use it in worker threads to notify
the main thread of something that happens in the thread (without the


Where do you find this purpose.  As Mattias said, the spec says 
nothing of the sort.



Otherwise adding a critical section to all the async queue methods is
in order.


IMOH protecting a call to QueueAsyncCall() (in user code or IMHO
better in the LCL itself) by a semaphore should not harm anyway in most
cases, as there would be no waiting on anything else in that critical
section. If you assign different priorities to the threads there of
course is the usual problem of priority inversion.


Protecting it in user code won't work, since the application can still 
remove calls while you try and add them.  It needs to be protected 
inside the lcl or fail.


Henry

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Michael Schnell

On 06/09/2011 12:10 PM, Henry Vermaak wrote:


This will not even solve the problem, since the ProcessAsyncCallQueue 
and RemoveAsyncCalls also need to be protected. 

This is what I seem to have found, too.
But it can't be done in user code which never calls RemoveAsyncCalls(). 
If it is really necessary (analyzing the code on that behalf does not 
seem trivial) it needs to be done within the LCL.



Just use PostMessage for thread communication.


IMHO instead of using the old Windowish stuff,  better the problems in 
the LCL should be resolved.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Michael Schnell

On 06/09/2011 12:30 PM, Henry Vermaak wrote:
Where do you find this purpose.  As Mattias said, the spec says 
nothing of the sort.

I don't see any other purpose.;-)
Protecting it in user code won't work, since the application can still 
remove calls while you try and add them.  It needs to be protected 
inside the lcl or fail.

Obviously, here we agree :-) .
Should a issue report be filed ?

-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Mattias Gaertner
 
 

 Henry Vermaak henry.verm...@gmail.com hat am 9. Juni 2011 um 12:12
geschrieben:

  On 09/06/11 11:01, Mattias Gaertner wrote:
  
  
   Michael Schnell mschn...@lumino.de hat am 9. Juni 2011 um 11:46
   geschrieben:
  
     On 06/09/2011 10:58 AM, Henry Vermaak wrote:
      You will corrupt the linked list that QueueAsyncCall() uses when you
      call it from multiple threads, so you _must_ protect it.
     As QueueAsyncCall is specified exactly for this use, it needs to take
     care of this issue internally. Otherwise it obviously is buggy. I trust
     that the LCL developers did a decent job.
  
   The only specification I found for TApplication.QueueAsyncCall is the
   fpdoc entry:
  
   Insert a given asynchronous call into the queue
  
   Why do you think it is thread safe?
 
  Do you propose that QueueAsyncCall throws an exception if it's used from
  outside the main thread?  Otherwise adding a critical section to all the
  async queue methods is in order.
 I made it thread safe. Please test.

 Mattias--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Mattias Gaertner
 
 

 Michael Schnell mschn...@lumino.de hat am 9. Juni 2011 um 12:39 geschrieben:

  On 06/09/2011 12:30 PM, Henry Vermaak wrote:
   Where do you find this purpose.  As Mattias said, the spec says
   nothing of the sort.
  I don't see any other purpose.;-) 
Well, that is an argument from ignorance.
 
The purpose is to execute a method outside the event where it was initiated. For
example to free a TEdit inside its OnKeyDown event or to switch the focus in an
OnEnter event.
 

 Mattias

Argument from ignorance--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Henry Vermaak

On 09/06/11 11:39, Michael Schnell wrote:

On 06/09/2011 12:30 PM, Henry Vermaak wrote:

Where do you find this purpose. As Mattias said, the spec says
nothing of the sort.

I don't see any other purpose.;-)


Bad eyesight?

Henry

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Graeme Geldenhuys
On 09/06/2011 13:17, Mattias Gaertner wrote:
 
 Well, that is an argument from ignorance.

Then the documentation was written by the arrogant - expecting everybody
else to be mind readers.


 The purpose is to execute a method outside the event where it was
 initiated. For example to free a TEdit inside its OnKeyDown event or to
 switch the focus in an OnEnter event.

While you are at it, would you mind updating the documentation for
QueueAsyncCall() - thus avoiding any future confusion.



Regards,
  - Graeme -

-- 
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Henry Vermaak

On 09/06/11 12:00, Mattias Gaertner wrote:



Henry Vermaak henry.verm...@gmail.com hat am 9. Juni 2011 um 12:12
geschrieben:

  On 09/06/11 11:01, Mattias Gaertner wrote:
  
  
   Michael Schnell mschn...@lumino.de hat am 9. Juni 2011 um 11:46
   geschrieben:
  
On 06/09/2011 10:58 AM, Henry Vermaak wrote:
 You will corrupt the linked list that QueueAsyncCall() uses
when you
 call it from multiple threads, so you _must_ protect it.
As QueueAsyncCall is specified exactly for this use, it needs to take
care of this issue internally. Otherwise it obviously is buggy. I
trust
that the LCL developers did a decent job.
  
   The only specification I found for TApplication.QueueAsyncCall is the
   fpdoc entry:
  
   Insert a given asynchronous call into the queue
  
   Why do you think it is thread safe?
 
  Do you propose that QueueAsyncCall throws an exception if it's used from
  outside the main thread? Otherwise adding a critical section to all the
  async queue methods is in order.

I made it thread safe. Please test.


In TApplication.Destroy there is another call to ProcessAsyncCallQueue 
further down (line 170).  System.DoneCriticalSection(FAsyncCall.CritSec) 
needs to be moved after it.


Henry

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Mattias Gaertner
 
 

 Graeme Geldenhuys graemeg.li...@gmail.com hat am 9. Juni 2011 um 13:22
geschrieben:

  On 09/06/2011 13:17, Mattias Gaertner wrote:
  
   Well, that is an argument from ignorance.
 
  Then the documentation was written by the arrogant - expecting everybody
  else to be mind readers. 
I think you overstate it. The LCL is not thread safe. It's said on the multi
threading tutorial and it is the standard example for TThread.Synchronize. 
Only if the documentation explicitly says a method is thread safe it is. Maybe
this needs to be made more clear. Any ideas, where?
There are a few low level functions like FileExistsUTF8 which are thread safe
and needs to be documented that they are. 
 
 

 
 
   The purpose is to execute a method outside the event where it was
   initiated. For example to free a TEdit inside its OnKeyDown event or to
   switch the focus in an OnEnter event.
 
  While you are at it, would you mind updating the documentation for
  QueueAsyncCall() - thus avoiding any future confusion.
 Ah, I forgot to commit the docs directory.

 Mattias--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Mattias Gaertner
 
 

 Henry Vermaak henry.verm...@gmail.com hat am 9. Juni 2011 um 13:28
geschrieben:

 [...] In TApplication.Destroy there is another call to ProcessAsyncCallQueue
  further down (line 170).  System.DoneCriticalSection(FAsyncCall.CritSec)
  needs to be moved after it.
 Done.

 Mattias--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Michael Schnell

On 06/09/2011 01:00 PM, Mattias Gaertner wrote:


I made it thread safe. Please test.



Thanks Mattias, you made my day !

Reading the other messages here, I actually considered unsubscribing 
from the list and forgetting about Lazarus altogether.


(A decent library needs to be usable ion a threaded project, even of of 
course not all functions can be genuinely thread safe.)


-Michael
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Henry Vermaak

On 09/06/11 12:55, Mattias Gaertner wrote:



Henry Vermaak henry.verm...@gmail.com hat am 9. Juni 2011 um 13:28
geschrieben:

 [...] In TApplication.Destroy there is another call to
ProcessAsyncCallQueue
  further down (line 170). System.DoneCriticalSection(FAsyncCall.CritSec)
  needs to be moved after it.

Done.


Thanks!  Works here now.

Henry

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Henry Vermaak

On 09/06/11 13:04, Michael Schnell wrote:

  On 06/09/2011 01:00 PM, Mattias Gaertner wrote:


I made it thread safe. Please test.



Thanks Mattias, you made my day !

Reading the other messages here, I actually considered unsubscribing
from the list and forgetting about Lazarus altogether.


What pathetic attitude.  You can fix these things yourself, but never 
do.  It's always just talk with you, isn't it?


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Michael Schnell

On 06/09/2011 01:00 PM, Mattias Gaertner wrote:

I made it thread safe. Please test.
I verified that it works with my thread testing project (but I did not 
notice a problem before).


Some thoughts:

Did you verify that in a single worker thread situation the protection 
is necessary ? The worker thread only modifies one end of the queue, the 
main thread only modifies the other end. So hazards are only possible 
when the queue is nearly empty. No inc or dec seems to be done, so there 
are chances that it's thread safe by default.


I can't understand, why RemoveAsyncCalls seems to remove two entries 
from the queue. Do you know what is happening there ?


Thanks,
-Michael
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Michael Schnell

On 06/09/2011 02:29 PM, Henry Vermaak wrote:


What pathetic attitude.  You can fix these things yourself, but never do.

I don't want to destroy something that somebody more knowledgeable created.

It's always just talk with you, isn't it?
Right now you are correct. (I do hope that my contributions provide some 
help for improving the already great tool.)


As you might know I did some active work on a Widget Type some years 
ago, but found that the results are not according to a standard that I 
feel valid for publishing.


At the moment, for me the Pascal projects are very low priority, so I 
can't dedicate much more time than reading the list, providing some 
thoughts and do some testing. But this might change greatly at some 
point in time that is not due to my decision.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Felipe Monteiro de Carvalho
On Thu, Jun 9, 2011 at 2:42 PM, Michael Schnell mschn...@lumino.de wrote:
 I don't want to destroy something that somebody more knowledgeable created.

This risk does not exist, patches are discussed and reviewed before
being applyed.

-- 
Felipe Monteiro de Carvalho

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Flávio Etrusco
On Thu, Jun 9, 2011 at 9:29 AM, Henry Vermaak henry.verm...@gmail.com wrote:
 On 09/06/11 13:04, Michael Schnell wrote:

  On 06/09/2011 01:00 PM, Mattias Gaertner wrote:

 I made it thread safe. Please test.


 Thanks Mattias, you made my day !

 Reading the other messages here, I actually considered unsubscribing
 from the list and forgetting about Lazarus altogether.

 What pathetic attitude.  You can fix these things yourself, but never do.
  It's always just talk with you, isn't it?

 --

Nobody were asking for patches, just discussing behaviour. And I
completely agree with Michael in that QueueAsyncCall ought to be
thread-safe (thanks from me too, Mattias!).

-Flávio

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-09 Thread Krzysztof
Huh, 35 new messages in my topic :) . After reading all, maybe I summarize
why I need post message to non-windowed object/component and why I can't use
PostMessage and for what I need this (on a real example).

So, I wrote TMyHTTPClient which is some kind of layer for synapse http
client but it do all jobs in thread. Simply structure:

type
  TMyHTTPClient = class;

  TSynThread = class(TThread)
  private
FMyHClient: TMyHTTPClient;
FSynHTTP: THTTPSend;
  end;

  TMyHTTPClient = class
  private
FSynThread: TSynThread;
  end;

Now, TSynThread communicate with TMyHTTPClient sending progress and response
data from server. I used TThread.Synchronize() for this but I often had
deadlocks because TMyHTTPClient cares about terminate and free thread (it
waiting in destructor until thread terminate). I could not find way to omit
deadlocks in case when thread blocking in synchronize() to send progress
data and TMyHTTPClient waiting for this thread termination (ProcessMessages
and CheckForSynchronize doesn't solve this on linux). So I tried solve this
using PostMessage instead of Synchronize but PostMessage need window handle.
In simple project, main form should be solution here (as mediator
between TMyHTTPClient
and TSynThread) but my project is quite big and I use this http client in
many places, in many modules, in many cases (most in non-visual) and in many
instances. So I need something simpler. Now you reminded me about
Application.QueueAsyncCall and this is point where we are :) . I think that
critical section latency in thread is not problem in this case. I try update
lazarus source and test your thread safe fix for QueueAsyncCall.
Maybe my case could be resolved in many different ways, but good
communication mechanism between threads, certainly will be useful in
other cases :)
Sorry for my bad english, I tried describe it in details.

Regards.
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


[Lazarus] How to PostMessage to object?

2011-06-08 Thread Krzysztof
Hi,

How can I PostMessage from thread to another object? PostMessage/SendMessage
need HWND as parameter but this kind of handle is only in visual controls
(TWinControl, TForm). I temporary can use TWinControl type instead of
TObject but it need parent window to handle messages. Exists any cross
platform solution for this? I found only this article for windows (I can't
find DefWindowProc in lazarus)
http://www.delphidabbler.com/articles?article=1

Regards.
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-08 Thread Michael Schnell

On 06/08/2011 04:57 PM, Krzysztof wrote:

How can I PostMessage from thread to another object?
While PostMessage() and Procedure...Message is available with 
Lazarus, you better use the non-Windowish Application.QueueAsyncCall() 
procedure.


BTW.: with Delphi, you mostly better user TThread.Queue for this purpose.

-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-08 Thread Krzysztof
Hm, I forgot about Application.QueueAsyncCall. And this can be safely call
from thread without TThread.Synchronize() ? Because I don't want use
Synchronize() in any part of thread code. So this is correct code? :

procedure TMyThread.Execute;
begin
  // some code here
  Application.QueueAsyncCall(@SomeObj.TestMethod, PtrInt(NewStr('Some
value')));
  // some code here
end;

There is no chance for deadlock with main thread calling this from inside
another thread?
But can be problem here if thread try call Application.QueueAsyncCall for
object which was freed (AV occur). PostMessage just return false if handle
doesn't exists.

2011/6/8 Michael Schnell mschn...@lumino.de

 On 06/08/2011 04:57 PM, Krzysztof wrote:

 How can I PostMessage from thread to another object?

 While PostMessage() and Procedure...Message is available with Lazarus,
 you better use the non-Windowish Application.QueueAsyncCall() procedure.

 BTW.: with Delphi, you mostly better user TThread.Queue for this purpose.

 -Michael

 --
 ___
 Lazarus mailing list
 Lazarus@lists.lazarus.freepascal.org
 http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-08 Thread Henry Vermaak

On 08/06/11 16:28, Krzysztof wrote:

Hm, I forgot about Application.QueueAsyncCall. And this can be safely
call from thread without TThread.Synchronize() ? Because I don't want
use Synchronize() in any part of thread code. So this is correct code? :

procedure TMyThread.Execute;
begin
   // some code here
   Application.QueueAsyncCall(@SomeObj.TestMethod, PtrInt(NewStr('Some
value')));
   // some code here
end;

There is no chance for deadlock with main thread calling this from
inside another thread?


You have to protect it with a critical section (if you have more than 
one thread calling QueueAsyncCall).


Henry

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-08 Thread Krzysztof
Ok, this can be done with critical section but what with AV scenario?
Example:
1. Thread add queue calling Application.QueueAsyncCall(MyObj.EventMethod,
0);
2. MyObj is destroyed by main thread
3. Main thread process messages and try call queue added by thread but
reference to MyObj.EventMethod was destroyed by previous message loop. This
cause Access Violation.

I could remove this queue in MyObj destructor but TApplication.FAsyncCall is
in private section :/

2011/6/8 Henry Vermaak henry.verm...@gmail.com

 On 08/06/11 16:28, Krzysztof wrote:

 Hm, I forgot about Application.QueueAsyncCall. And this can be safely
 call from thread without TThread.Synchronize() ? Because I don't want
 use Synchronize() in any part of thread code. So this is correct code? :

 procedure TMyThread.Execute;
 begin
   // some code here
   Application.QueueAsyncCall(@SomeObj.TestMethod, PtrInt(NewStr('Some
 value')));
   // some code here
 end;

 There is no chance for deadlock with main thread calling this from
 inside another thread?


 You have to protect it with a critical section (if you have more than one
 thread calling QueueAsyncCall).

 Henry


 --
 ___
 Lazarus mailing list
 Lazarus@lists.lazarus.freepascal.org
 http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] How to PostMessage to object?

2011-06-08 Thread Krzysztof
Ok, I did not notice that exists method TApplication.RemoveAsyncCalls(const
AnObject: TObject). Anyway it's strange that AnObject param is compared to
Data param from QueueAsyncCall, not to AMethod, but this is not a problem.

2011/6/8 Krzysztof dib...@wp.pl

 Ok, this can be done with critical section but what with AV scenario?
 Example:
 1. Thread add queue calling Application.QueueAsyncCall(MyObj.EventMethod,
 0);
 2. MyObj is destroyed by main thread
 3. Main thread process messages and try call queue added by thread but
 reference to MyObj.EventMethod was destroyed by previous message loop. This
 cause Access Violation.

 I could remove this queue in MyObj destructor but TApplication.FAsyncCall
 is in private section :/

 2011/6/8 Henry Vermaak henry.verm...@gmail.com

 On 08/06/11 16:28, Krzysztof wrote:

 Hm, I forgot about Application.QueueAsyncCall. And this can be safely
 call from thread without TThread.Synchronize() ? Because I don't want
 use Synchronize() in any part of thread code. So this is correct code? :

 procedure TMyThread.Execute;
 begin
   // some code here
   Application.QueueAsyncCall(@SomeObj.TestMethod, PtrInt(NewStr('Some
 value')));
   // some code here
 end;

 There is no chance for deadlock with main thread calling this from
 inside another thread?


 You have to protect it with a critical section (if you have more than one
 thread calling QueueAsyncCall).

 Henry


 --
 ___
 Lazarus mailing list
 Lazarus@lists.lazarus.freepascal.org
 http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus



--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus