Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2011-10

Are multiple critical sections allowed in form or data module?

24 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Frank Church

Are multiple critical sections allowed in form or data module?

e.g. I have different datasets each with its own connection and queries that threads need to lookup data from.

Is it acceptable to have additional TCriticalSections on the form?

Frank Church ======================= http://devblog.brahmancreations.com -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20111009/44f04c3e/attachment.html>

Reply by email

Mattias Gaertner
to Frank Church
Show quoted text 6 lines
Are multiple critical sections allowed in form or data module? e.g. I have different datasets each with its own connection and queries that threads need to lookup data from. Is it acceptable to have additional TCriticalSections on the form?

Yes.
I hope you are aware that all code accessing the LCL must run in the main thread.

Mattias

Reply by email

Frank Church
to Mattias Gaertner
Mattias Gaertner wrote 18 lines
On Sun, 9 Oct 2011 00:22:10 +0100 Frank Church wrote: > Are multiple critical sections allowed in form or data module? > > e.g. I have different datasets each with its own connection and queries that > threads need to lookup data from. > > Is it acceptable to have additional TCriticalSections on the form? Yes. I hope you are aware that all code accessing the LCL must run in the main thread. Mattias

Can you explain this?
Do you mean that TCriticalSection is part of the LCL and shouldn't be run from within a thread, or that code within the thread or the critical section must not run code accessing the LCL?

How is it determined whether a piece of code runs within the LCL or not?

Show quoted text 7 lines
-- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Frank Church ======================= http://devblog.brahmancreations.com -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20111009/eedf796e/attachment-0001.html>

Reply by email

Mattias Gaertner
to Frank Church
Show quoted text 24 lines
On 9 October 2011 07:30, Mattias Gaertner wrote: > On Sun, 9 Oct 2011 00:22:10 +0100 > Frank Church wrote: > > > Are multiple critical sections allowed in form or data module? > > > > e.g. I have different datasets each with its own connection and queries > that > > threads need to lookup data from. > > > > Is it acceptable to have additional TCriticalSections on the form? > > Yes. > I hope you are aware that all code accessing the LCL must run in the > main thread. > > Mattias > > Can you explain this? Do you mean that TCriticalSection is part of the LCL and shouldn't be run from within a thread, or that code within the thread or the critical section must not run code accessing the LCL?

All LCL code that deals with Application, TControl or widget handles is not thread safe and should only be accessed by the main thread. When another thread needs to access these LCL parts it should do it via the main thread, for example via Synchronize.

How is it determined whether a piece of code runs within the LCL or not?
if GetCurrentThreadID=MainThreadID then

Mattias

Reply by email

Hans-Peter Diettrich
to Frank Church: Can you explain this? Do you mean that TCriticalSection is part of the LCL and shouldn't…
Show quoted text 10 lines
> Is it acceptable to have additional TCriticalSections on the form? Yes. I hope you are aware that all code accessing the LCL must run in the main thread. Mattias Can you explain this?

A critical section blocks all code, that wants to enter the same (occupied) critical section, until the current owner left the critical section. You can have any number of critical section objects, and they can be used in a nested manor - at the risk of deadlocks.

Do you mean that TCriticalSection is part of the LCL and shouldn't be run from within a thread, or that code within the thread or the critical section must not run code accessing the LCL?

The LCL is not reentrant. All code accessing the LCL should run in the main thread (see Synchronize...), not in other threads.

How is it determined whether a piece of code runs within the LCL or not?

Wrong question :-(

Whenever your code accesses a procedure or object of the LCL, that code should not reside (and execute) in an thread. A thread should provide a (callback) method instead, which contains such code, and make that method execute in the main thread (see Synchronize...).

I'm not sure how some code can determine, whether it runs in the main thread.

DoDi

Reply by email

Hans-Peter Diettrich
to Mattias Gaertner: On Sun, 09 Oct 2011 10:49:31 +0200 Most LCL code is reentrant. An event can trigger an…
Show quoted text 7 lines
On Sun, 09 Oct 2011 10:49:31 +0200 Hans-Peter Diettrich wrote: > [...] > The LCL is not reentrant. Most LCL code is reentrant.

Only within the context of an single thread.

This was acceptable on traditional single-CPU/core machines, but nowadays non-visual components, and also parts of a GUI, should be manageable in different (dedicated) threads.

DoDi

Reply by email

Michael Van Canneyt
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote 14 lines
Mattias Gaertner schrieb: > On Sun, 09 Oct 2011 10:49:31 +0200 > Hans-Peter Diettrich wrote: > >> [...] >> The LCL is not reentrant. > > Most LCL code is reentrant. Only within the context of an single thread. This was acceptable on traditional single-CPU/core machines, but nowadays non-visual components, and also parts of a GUI, should be manageable in different (dedicated) threads.

It's not so on Unix. X-Windows is definitely not thread-safe.

I also have not seen any claims from Microsoft that the GDI controls are thread-safe, and according to

http://stackoverflow.com/questions/2798812/net-controls-why-arent-all-calls-thread-safe

it is simply not thread safe, some exceptions aside.

The argument put forward there is a sane one: only the programmer can meaningfully decide on the granularity of the needed marshalling. A framework never can do that.

Michael.

Reply by email

Hans-Peter Diettrich
to Michael Van Canneyt
Show quoted text 23 lines
On Sun, 9 Oct 2011, Hans-Peter Diettrich wrote: > Mattias Gaertner schrieb: >> On Sun, 09 Oct 2011 10:49:31 +0200 >> Hans-Peter Diettrich wrote: >> >>> [...] >>> The LCL is not reentrant. >> >> Most LCL code is reentrant. > > Only within the context of an single thread. > > This was acceptable on traditional single-CPU/core machines, but > nowadays non-visual components, and also parts of a GUI, should be > manageable in different (dedicated) threads. It's not so on Unix. X-Windows is definitely not thread-safe. I also have not seen any claims from Microsoft that the GDI controls are thread-safe,

True, widgetsets typically are not threadsafe, that's not the problem. Remember an recent thread, where e.g. a progress bar could be attached to and served by an thread, independently from the main application GUI. The same for data modules...

DoDi

Reply by email

Michael Schnell
to Frank Church: Are multiple critical sections allowed in form or data module? e.g. I have different…
Frank Church wrote
Are multiple critical sections allowed in form or data module?

I don't understand your concern.

A DataModule is a way to organize the makeup and dependance of objects (so strictly a question of data in memory).

A CriticalSection is a way to organize the instruction flow.

So they have close to no connection.

(In short: Yes)

-Michael

Reply by email

Michael Schnell
to Frank Church: Can you explain this? Do you mean that TCriticalSection is part of the LCL and shouldn't…
Frank Church wrote 6 lines
Do you mean that TCriticalSection is part of the LCL and shouldn't be run from within a thread, or that code within the thread or the critical section must not run code accessing the LCL?

TCriticalSection is obviously done to be used in Thread.

How is it determined whether a piece of code runs within the LCL or not?

The documentation on this is rather poor. (E.g. the "Thread-Safety" of Tlist has recently been discussed.)

In fact the help for any LCL and RTL function should say how it can be used regarding threads.

It is known that any function that accesses the GUI can only be called by the main thread. You might get a runtime error when violating this rule, but there is no purposeful

Reply by email

Michael Schnell
to Mattias Gaertner: On Sun, 9 Oct 2011 08:14:41 +0100 All LCL code that deals with Application, TControl or…
Mattias Gaertner wrote 6 lines
On Sun, 9 Oct 2011 08:14:41 +0100 Frank Church wrote: > How is it determined whether a piece of code runs within the LCL or not? if GetCurrentThreadID=MainThreadID then

I understand his question as "How to find out whether a function in the RTL is allowed to be called by a thread? "

Here only the documentation can help. When it is not elaborated enough you need good intuition.

-Michael

Reply by email

Michael Schnell
to Hans-Peter Diettrich: A critical section blocks all code, that wants to enter the same (occupied) critical…
Hans-Peter Diettrich wrote
The LCL is not reentrant. All code accessing the LCL should run in the main thread (see Synchronize...), not in other threads.

Not true in this intensity.

There are functions in the LCL especially doe not be called by worker Threads, and there are certain functions in the LCL that can be called by the main threads and by worker thread.

Moreover there are complicated cases (Like TList in the RTL the functions of which are only "thread save" when the threads don't use the same instance, while TThreadList is documented to be always thread save.)

-Michael

Reply by email

Michael Schnell
to Hans-Peter Diettrich: Only within the context of an single thread. This was acceptable on traditional…
Hans-Peter Diettrich wrote 6 lines
Mattias Gaertner schrieb: > > Most LCL code is reentrant. Only within the context of an single thread.

In a single threadded application only recursive functions can have reentrancy problems.

As nearly all user code is done as an event (callback) from the LCL the LCL is always called in a recursive way and thus is is bound to be reentrant-save to a certain extent.

-Michael

Reply by email

Michael Schnell
to Michael Van Canneyt: It's not so on Unix. X-Windows is definitely not thread-safe. I also have not seen any…
Michael Van Canneyt wrote
It's not so on Unix. X-Windows is definitely not thread-safe.

Of course "in general" this is correct.

But I understand that it should be possible that an application (using additional threads) creates more than one "Main Frame" by attaching to a new "instance" of the Widget set and thus - regarding the GUI - acts as multiple applications, (But quite obviously the LCL does not support this, as it uses some global variables to manage the "Application".)

-Michael

Reply by email

Unknown author
to Michael Schnell
Michael Schnell wrote 9 lines
On 10/09/2011 03:14 PM, Michael Van Canneyt wrote: > It's not so on Unix. X-Windows is definitely not thread-safe. Of course "in general" this is correct. But I understand that it should be possible that an application (using additional threads) creates more than one "Main Frame" by attaching to a new "instance" of the Widget set and thus - regarding the GUI - acts as multiple applications, (But quite obviously the LCL does not support this, as it uses some global variables to manage the "Application".)

I don't think that the LCL should support this.
It adds another layer of complexity for no good reason at all, with questionable end-results.

See the link I posted for a good explanation of why this is a bad idea.

Michael.

Reply by email

Michael Schnell
to Unknown author: I don't think that the LCL should support this. It adds another layer of complexity for…
I don't think that the LCL should support this.

I did not want to suggest that it should (IMHO it would be "nice" to have this as a special Application type, but it's (a) not easy to do and (b) quite low priority. I in fact do have a (Delphi) application that would benefit of allowing a multi-threaded GUI on a multi-core machine. But I recon that this is a very uncommon case.)

It adds another layer of complexity for no good reason at all, with questionable end-results.

I fully agree.

-Michael

Reply by email

Michael Schnell
to Hans-Peter Diettrich: Currently it's sufficient to know that the LCL is not threadsafe. That's one of the…
Hans-Peter Diettrich wrote 6 lines
Michael Schnell schrieb: > In fact the help for any LCL and RTL function should say how it can > be used regarding threads. Currently it's sufficient to know that the LCL is not threadsafe.

So you claim that nobody should use Application.QueuAsyncCall() ?!?!?!

IMHO same is a very powerful and portable and thus indispensable way to do a notification to the main frame and thus the GUI.

-Michael

Reply by email

Hans-Peter Diettrich
to Michael Schnell: TCriticalSection is obviously done to be used in Thread. The documentation on this is…
In fact the help for any LCL and RTL function should say how it can be used regarding threads.

Currently it's sufficient to know that the LCL is not threadsafe.

It is known that any function that accesses the GUI can only be called by the main thread.

That's one of the reasons, and since virtual methods and event handlers can be used almost everywhere, almost no method or property can ever be documented as being threadsafe.

DoDi

Reply by email

Hans-Peter Diettrich
to Michael Schnell: Of course "in general" this is correct. But I understand that it should be possible that…
Show quoted text 8 lines
On 10/09/2011 03:14 PM, Michael Van Canneyt wrote: > It's not so on Unix. X-Windows is definitely not thread-safe. Of course "in general" this is correct. But I understand that it should be possible that an application (using additional threads) creates more than one "Main Frame" by attaching to a new "instance" of the Widget set and thus - regarding the GUI - acts as multiple applications,

You cannot have multiple instances of an widgetset, and not multiple (different) widgetsets in one application.

What should be feasable are windows (forms) in more than only the main thread, when every thread uses its own message queue. Then a worker thread could e.g. update its progress indicator, in his own form, without blocking (or being blocked by) the main thread.

DoDi

Reply by email