Re: [Lazarus] How to PostMessage to object?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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