` Printed Icetips Article

Icetips Article



Par2: Clarion threads: workaround
2002-12-27 -- Owen Brunker
 
Analysis
==========
For some unknown reason the function THREAD() is intermittently returning
the wrong thread number for the current thread.  This doesn't appear to
cause a problem legacy templates. But with ABC templates this becomes a
nightmare.

Because global Clarion objects can't be created on a thread and the ABC file
manager objects, rely on tracking thread sensitive data, all thread
sensitive data is managed by keeping it in various queues.  The correct
thread sensitive data is retreived by tying the queue records to the thread
id returned by THREAD().  All the ABC file manager objects have thread
context detection mechanisms at the beginning of each of their methods to
make sure that the correct thread sensitive data is available.  The thread
context detection mechanisms rely on the call to THREAD() to determine which
thread is running and to get it's data.

The thread sensitive data tracked by the ABC file managers are as follows.
1. Counters which count the number of times a File has been opened on the
current thread
2. Saved copied of record buffers.
3. Saved copied of fields belonging to keys, needed for referential
integrity
during updates and deletes.

Common manifestations of an incorrect thread id returned by THREAD() are
complaints from the file managers that files haven't been closed and bind
errors.  More serious problems that I have encountered is to do with the
referential integrity of my apps eg. The time sheets of one employee jumping
to another employee because of an unexpected cascade update resulting from
the file manager using data from another thread context.

As described in the analysis,  the issue is the THREAD() function.  If the
problem was deeper than this we would be seeing problems manifesting within
the applications using the LEGACY templates.  These LEGACY applications are
remarkebly free of problems.  We have one such system deployed in C5.5 that
runs with little or no problems.

Solution
==========
The solution to the problem is to replace the THREAD() function with
GetCurrentThreadId().  GetCurrentThreadId() is a function provided by the
Win32 API and returns a thread id in the form of a ULONG that is unique
system wide.  The fact is that in Win32 applications, Clarion does use
Operating System threads but keeps them locked to protect against
re-entrancy problems in the runtime libraries.  Somewhere internally it is
translating a thread's id provided by the system to its own numbering
system.

The easiest way to replace the THREAD() function is modify BUILTINS.CLW so
that any call to THREAD() results in a call to GetCurrentThreadId().  As
GetCurrentThreadId() returns a ULONG, a scan of all code to check the size
of variables used to store thread ids is probably important.  Recompile your
app after these changes and give it a good work out.



Printed November 21, 2024, 7:29 am
This article has been viewed/printed 35475 times.