Root > Integral parts > Options > Features page > Multi-threading page

Multi-threading page

Previous pageReturn to chapter overviewNext page   

This is "Multi-threading" page in EurekaLog project's options.

 

 

Multi-threading options

 

Options on "Multi-threading" page allow you to customize EurekaLog's multi-threading behavior.

 

1. "Automatically activated background threads" option specifies default EurekaLog state for new background threads:

If this option is set to "Disabled" - new threads will have EurekaLog disabled. It is recommended value.
If this option is set to "Enabled" - new threads will have EurekaLog enabled. It is not recommended value.
If this option is set to "Enabled for RTL threads, disabled for Windows threads" - threads created with BeginThread or TThread will have EurekaLog enabled, threads created with CreateThread will have EurekaLog disabled.

 

You can turn EurekaLog on/off on per-thread basis when creating threads or using SetEurekaLogStateInThread function inside thread itself.

 

You can use this option to enable EurekaLog for threads which you have no control of. Like system worker threads, thread pool, etc. You can always change per-thread EurekaLog state manually from your code.

 

It's highly recommended to keep this option into "Disabled" state and enable EurekaLog manually in your threads only - to avoid EurekaLog processing in 3rd party threads. See Using EurekaLog in multi-threaded applications for more details.

 

Important Note: Try to never use "Enabled" option as it will enable EurekaLog for all threads in your application - including internal system threads. Use "Enabled for RTL threads, disabled for Windows threads" instead of "Enabled" when possible.

 

 

2. "Include stacks of EurekaLog-enabled threads" (.csoShowELThreads) option includes call stacks of all EurekaLog-enabled threads in application - regardless of thread type. By default only exception thread is captured.

 

"EurekaLog-enabled thread" term refers to thread with enabled per-thread EurekaLog. You can enable EurekaLog in any thread by calling SetEurekaLogStateInThread function or just simply create threads with TThreadEx or BeginThreadEx. See Enabling EurekaLog for background threads for more details.

 

Turn this option off for single-threaded application.

Turn this option on for multi-threaded application.

 

Taking call stack of additional threads will also require more time during exception processing.

 

Important Note: This option does NOT control if EurekaLog should automatically catch exceptions in threads. See options above.

 

 

3. "Include stacks of RTL threads" (.csoShowRTLThreads) option includes call stacks of all RTL threads in application. By default only exception thread is captured.

 

"RTL threads" means threads started with TThread or BeginThread.

 

It is recommended to keep this option off and use TThreadEx and BeginThreadEx or SetEurekaLogStateInThread together with "Include stacks of EurekaLog-enabled threads" option instead.

Turn this option on to capture call stack of external RTL threads (that is threads started by 3rd party code without your control).

 

Taking call stack of additional threads will require more time during exception processing.

 

Important Note: This option does NOT control if EurekaLog should automatically catch exceptions in threads. See options above.

 

 

4. "Include stacks of Windows threads" (.csoShowWindowsThreads) option includes call stacks of all non-RTL threads in application. By default only exception thread is captured.

 

"Windows threads" means threads started with CreateThread.

 

It is recommended to keep this option off and use TThreadEx and BeginThreadEx or SetEurekaLogStateInThread together with "Include stacks of EurekaLog-enabled threads" option instead. Alternatively, you may use "Include stacks of RTL threads" option instead.

 

Turn this option on to capture call stack of external Windows threads (that is threads started by 3rd party code without your control).

Never start your own thread with CreateThread function.

 

Taking call stack of additional threads will require more time during exception processing.

 

Important Note: This option does NOT control if EurekaLog should automatically catch exceptions in threads. See options above.

 

 

5. "Consecutive processing" option (.ConsecutiveProcessing) acquires a global lock during exception processing.

 

Checked: only single thread may process exceptions at the same time.

Unchecked: threads may process exceptions simultaneously.

 

While not recommended, but you can enable this option for visual/GUI multi-threaded applications which show exception dialogs from background threads.

We recommend to disable this option for all non-visual applications.

 

Enabling this option means that simultaneous exceptions will be processed (shown) one after another in a consecutive manner. E.g. only one dialog will be visible at the same time. It also mean that exception processing performance will be lower, because several threads will be unable to process multiple exceptions at the same time. For this reason - we recommend to write your code in a such way that only main thread will show exception dialogs. Thus, you will not need to enable this option. You can achieve this by using TThread(Ex) and handling .FatalException property in the main thread.

 

Important Note: enabling this option does not mean that you can avoid adding proper synchronization to your EurekaLog's event handlers if you are accessing global data, because exception processing will be performed by active thread. E.g. exception in a background thread will be processed by the same background thread, and event handlers will be called by the same background thread. On other hand, introducing additional locks may lead to a deadlock in rare cases. Therefore, we recommend to avoid using global data in your EurekaLog's event handlers if you enable this option.

 

Important Note: this option affects exception processing only for exception from multiple background threads. It does nothing to alter behavior of multiple exceptions within a single thread. For example, if you have a code like this:

 

// Timer fires every second
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  // Your payload
  raise Exception.Create('Error Message');
end;

 

Then your main thread will raise a new exception every second:

1. Raising exception means showing EurekaLog dialog;
2. Showing any dialog means doing a message pumping cycle;
3. Doing message pumping means that more of your/3rd party code will run (e.g. timer in the example above);
4. Running your code means that new exception will/may be thrown;
5. Throwing new exception will trigger EurekaLog and show a new error dialog.

In other words, the code above will "spam" your desktop with error dialogs. This is the same behavior as in any application without EurekaLog.

 

One way to avoid this "spam" is to restart or terminate the application when exceptions occurs "too often". You can set/control this behavior by the restart/recovery options.

 

Another way to solve this issue is to modify your own code. Basically, the idea is to stop doing your work until EurekaLog dialog is closed, since "doing work" will/may raise another exception.

 

uses
  EException,      // for TEurekaExceptionInfo
  EEvents,         // for RegisterEventExceptionAction
  ETypes;          // for TEurekaActionType
 
threadvar
  // Indicates how many EurekaLog dialogs
  // are currently being displayed by
  // the current thread
  GProcessing: Integer;
 
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  // Do nothing if there is
  // an EurekaLog dialog on the screen
  if GProcessing <> 0 then
    Exit;
 
  // Your normal payload here
  raise Exception.Create('Error Message');
end;
 
// Monitors processing/dialogs
procedure SwitchProcessing
 (const ACustom: Pointer;
  AExceptionInfo: TEurekaExceptionInfo;
  const AEurekaAction: TEurekaActionType;
  const AAdditionalInfo: String;
  var AExecute: Boolean;
  var ACallNextHandler: Boolean);
begin
  // Entering processing/dialog
  if AEurekaAction = atExceptionHandling then
               // or atShowingExceptionInfo
    Inc(GProcessing)
  else
  // Leaving processing/dialog
  if AEurekaAction = atExceptionHandled then
               // or atShowedExceptionInfo 
    Dec(GProcessing);
end;
 
initialization
  // Instruct EurekaLog to switch your global flag
  RegisterEventExceptionAction(nil, SwitchProcessing);
end.

 

 

6. "Terminate threads on shutdown" option instructs EurekaLog to terminate running background threads before exiting application:

If this option is set to "Disabled" - EurekaLog will not terminate any threads when application is exiting. It is recommended value.
If this option is set to "Terminate all threads" - EurekaLog will terminate all background threads.
If this option is set to "Terminate RTL threads only" - EurekaLog will terminate only threads created with BeginThread(Ex) and TThread(Ex). EurekaLog will not terminate threads created with CreateThread.
If this option is set to "Terminate EurekaLog-enabled threads only" - EurekaLog will terminate only threads which have EurekaLog active, regardless of creating function.

 

Normally, your code should gracefully shutdown any background thread before you attempt to exit application. However, if you fail to do this (for example, using when using TThread.FreeOnTerminate) - a working background thread may interfere with shutdown (especially if there would be exceptions or leaks). While it is always better to refactor your code so it will stop threads before exiting application, you can use this option to terminate background threads on shutdown.

 

Important Note: Enabling this option may hang your application at shutdown, because EurekaLog may terminate background thread right when it is holding some sort of global lock.

 

 

7. "Pause all EurekaLog-enabled threads during exception handling" (.boPauseELThreads) option will force EurekaLog to suspend all threads with enabled EurekaLog before processing (handling) exception, and resume these threads when processing (handling) will be completed.

 

Use this option if you don't want for other exception to occur in multi-threaded applications when you're displaying error dialog. Alternative to this option is to properly setup exception handling for threads (serialize) or to use restart options. We recommend to keep this options turned off, and use "Consecutive processing" option instead (if really needed).

 

Notes:

It is recommended to keep this option off and use "Consecutive processing" instead.
In rare case suspending threads can cause deadlock issues (for example: thread may be suspended when it is running memory allocation function; thus, any further memory alloc/release operation will block application forever). Do not enable this option until really needed. See Using EurekaLog in multi-threaded applications for more details.

 

 

8. "Don't pause EurekaLog service threads" (.boDoNotPauseELServiceThread) option excludes internal EurekaLog service threads (such as freeze detection thread, etc.) from list of threads for suspending.

 

 

9. "Pause all RTL threads during exception handling" (.boPauseRTLThreads) option will force EurekaLog to suspend all threads in your application created with TThread or BeginThread before processing (handling) exception, and resume these threads when processing (handling) will be completed.

 

Use this option if you don't want for other exception to occur in multi-threaded applications when you're displaying error dialog. Alternative to this option is to properly setup exception handling for threads (serialize) or to use restart options.

 

Notes:

It is recommended to keep this option off and use "Consecutive processing" instead.
In rare case suspending threads can cause deadlock issues (for example: thread may be suspended when it is running memory allocation function; thus, any further memory alloc/release operation will block application forever). Do not enable this option until really needed. See Using EurekaLog in multi-threaded applications for more details.

 

 

10. "Don't pause main thread" (.boDoNotPauseMainThread) option excludes main thread from list of threads for suspending. Use this option if your event handlers are going to make synchronize calls into main thread.

 

Note: this option has no effect if "Pause all RTL threads during exception handling" and "Pause all EurekaLog-enabled threads during exception handling" options are not enabled.

 

 

11. "Pause all Windows threads during exception handling" (.boPauseWindowsThreads) option is equivalent to "Pause all RTL threads during exception handling" option, except this option will suspend/resume threads created with CreateThread function. Those threads are usually system service threads.

 

Use this option if you don't want for other exception to occur in multi-threaded applications when you're displaying error dialog. Alternative to this option is to properly setup exception handling for threads (serialize) or to use restart options.

 

Notes:

It is recommended to keep this option off and use "Consecutive processing" instead.
In rare case suspending threads can cause deadlock issues (for example: thread may be suspended when it is running memory allocation function; thus, any further memory alloc/release operation will block application forever). Do not enable this option until really needed. See Using EurekaLog in multi-threaded applications for more details.

 

 

12. "Auto-handle TThread exceptions" option enables backward-compatible EurekaLog 6 behavior for threads. When you enable this option - EurekaLog will automatically handle exception in TThread. Default behavior is not to handle exception, but allow it to be saved in TThread.FatalException property, which can be analyzed/handled by caller thread.

 

Warning: enabling this option may result in multiple error dialogs at the same time (if several exception occur in multiple threads) and interfere with custom processing of TThread.FatalException property.

 

Notes:

It's not recommended to use this option. You should implement proper error handling for threads instead. See Using EurekaLog in multi-threaded applications for more details.
EurekaLog has to be enabled for the background threads.

 

 

See also:




Send feedback... Build date: 2023-09-11
Last edited: 2023-03-07
PRIVACY STATEMENT
The documentation team uses the feedback submitted to improve the EurekaLog documentation. We do not use your e-mail address for any other purpose. We will remove your e-mail address from our system after the issue you are reporting has been resolved. While we are working to resolve this issue, we may send you an e-mail message to request more information about your feedback. After the issues have been addressed, we may send you an email message to let you know that your feedback has been addressed.


Permanent link to this article: https://www.eurekalog.com/help/eurekalog/multi_threading_page.php