Which thread will run a method of a TThread instance? (In Wait mode) - windows

When a TThread enters in Synchronized() method, it waits until EnterCriticalSection(ThreadLock) returns.
Now, which one will run the method if in the meantime, another Tthread, or even the main thread call some method of the waiting Tthread?

What could happen if in the meantime, another thread, or even the main thread call some method of the waiting thread?
Threads do not have methods, so this question is a non-sequitur.
It is not meaningful to ask what happens when you call a method of another thread. Because it is not possible to do so. When you call a method, that method executes on thread which called it.
A method like TThread.Synchronize schedules the execution of code onto a different thread. But, the body of TThread.Synchronize is executed by the thread of the caller.
A call to EnterCriticalSection cannot be interrupted by user mode code. So, suppose that thread A calls EnterCriticalSection at a point where thread B holds the lock. The call to EnterCriticalSection made on thread A will not return until thread B has released the lock. While thread A is blocked waiting to acquire the lock, no code will execute on thread A.
It seems, from clarifications in the comments, that your question is in fact:
When a method of TThread is called, on which thread does that method execute?
The answer is that the method is executed on the calling thread. There's nothing special about the TThread class and so the normal rules apply.

Related

Who is the calling thread of the callback function set by CreateTimerQueueTimer()?

I guess it's the thread, say A, on which the timer was created. But I can't figure out how exactly the callback function is called. Assume the timer expires, and then what happens? Does this happen when this thread gets its time slice? And if this is the case, I think the function should be called by the scheduler or what before the context is finally switched to A, then can I say A is the caller?
Thanks.
The timer callback can also be called by a pool thread, a thread that specifically manages timers or in the context of the creating thread, (the creating thread is designed to accept and process an 'Asynchronous Procedure Call'). The flag paramters in CTQT() control the action upon timer expiry.
If the timer event is called by a pool thread or timer-manager thread, that thread will become ready upon expiry and, when there is a core available to run it, it will make the callback 'immediately' within its own context. The thread that created the timer could, if it wished, wait on a synchro object, (event or semaphore), that could be signaled by the timer callback, (ie. normal inter-thread comms).
The timer callback can only be executed in the context of the thread that created it if that thread is in a position to execute the callback when it receives some sort of signal. In the case of these timers, an APC is QUEUED to the creating thread and, if that thread is blocked on one of the 'alertable' wait calls, it will become ready immediately, will run when there is a core available to run it. After the APC has run, the wait call will return. If the wait call is not SleepEx(), it will return WAIT_IO_COMPLETION - a result that is usually ignored. If the thread is not waiting when the APC is queued up, it will not be executed until the thread makes the next wait call, (obviously - since the thread must be off doing something else:).
'And if this is the case, I think the function should be called by the scheduler or what before the context is finally switched to A, then can I say A is the caller?' NO!

Can a thread call SuspendThread passing its own thread ID?

Can a Windows thread suspend itself with SuspendThread()?
I can awake it from another one but, can it call SuspendThread(GetCurrentThreadId())?
It seems this is possible, but with a slight alteration (see the cygwin mailing list discussing this here):
SuspendThread(GetCurrentThread());
I also found MSDN saying a thread should only suspend itself, but it doesn't make it clear for me. I quote (from here, emphasis mine):
This function is primarily designed for use by debuggers. It is not intended to be used for thread synchronization. Calling SuspendThread on a thread that owns a synchronization object, such as a mutex or critical section, can lead to a deadlock if the calling thread tries to obtain a synchronization object owned by a suspended thread. To avoid this situation, a thread within an application that is not a debugger should signal the other thread to suspend itself. The target thread must be designed to watch for this signal and respond appropriately.
Yes, you can use SuspendThread on current thread. Good read on the topic.
As a method of creating reusable threads for work tasks without the overhead of create and terminate tasks, suspend and resume thread could be used to quiesce a thread at the end of the task. When work is dispatch to the thread, resume it.

What happens if dispatch_main gets called from outside of the main thread?

The dispatch_main function is used to make the main thread start processing blocks dispatched to the main queue. So, dispatch_main is a kind of run loop, which doesn't return and, after processing the already-queued blocks, waits for other blocks to be submitted to the main queue.
So, what happens if dispatch_main gets called from outside of the main thread? If the main thread is processing another function, is it interrupted in order to allow the main thread to process the queued blocks? Is it allowed to call dispatch_main from outside of the main thread?
dispatch_main() asserts when called from outside of the main thread and aborts your process, it must only be called from the main thread.
dispatch_main() is really nothing other than pthread_exit() in disguise (see implementation): it turns the main queue into an ordinary serial dispatch queue and then terminates the main thread.
The main queue will be serviced by an on-demand workqueue thread from that point on, just like any other dispatch queue.

When a thread that calls SetWaitableTimer exits while another thread is waiting on the timer, is the timer cancelled?

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686289%28v=vs.85%29.aspx
According to msdn, in the remarks sections, it states:
"If the thread that set the timer terminates and there is an associated completion routine, the timer is canceled. However, the state of the timer remains unchanged. If there is no completion routine, then terminating the thread has no effect on the timer."
Then further down, it states:
"If the thread that called SetWaitableTimer exits, the timer is canceled. This stops the timer before it can be set to the signaled state and cancels outstanding APCs; it does not change the signaled state of the timer."
Hence my question,
if I have one thread calling SetWaitableTimer without an associated completion routine and another thread calling WaitOnMultipleObjects(passing in the timer object handle) and the thread that calls SetWaitiableTmer exits shortly thereafter, would the timer object be cancelled or would it still become signaled when the period expires?
To give more information directly from the implementation of waitable timers: if you use a CompletionRoutine, the timer is placed on a linked list chained off the thread which called SetWaitableTimer. When the thread is terminated, the kernel walks the dying thread's linked list and cancels are timers which are still queued.
If you're not using a completion routine, the timer is never added to any thread's linked list and thus isn't cancelled when any particular thread dies.
The documentation is somewhat unclear. I think the best you can do is test it yourself. I believe however that the timer cancels automatically only if the I/O completion routine is used.
I can give some "theoretical" background about windows APCs, to justify my (educated) guess.
APC = "asynchronous procedure call". In windows every user-mode thread is equipped with a so-called APC queue, a system-managed queue of procedures that must be called on this thread. A thread may enter a so-called "alertable wait" state (on purpose), during which it may execute one or more of the procedures in this queue. You may either put the procedure call in the APC queue manually, or issue an I/O, which on completion will "put" the procedure call there.
In simple words the scenario is the following: you issue several I/Os, and then you wait for either of them to complete (or fail), and, perhaps, some other events. You then call one of the alertable-waiting functions: SleepEx, WaitForMultipleObjectsEx or similar.
Important note: this mechanism is designed to support a single-threaded concurrency. That is, the same thread issues several I/Os, waits for something to happen, and responds appropriately. All the APC routines are guaranteed to be called in the same thread. Hence - if this thread exits - there's no way to call them. Hence - all the outstanding I/Os are also cancelled.
There are several Windows API functions that deal with asynchronous I/O, whereas they allow a choice of several completion mechanisms (such as ReadFileEx): APC, setting an event, or putting a completion in the I/O completion port. If those functions are used with APC - they automatically cancel the I/O if the issuing thread exits.
Hence, I guess that waitable timer auto-cancels only if used with APC.

Recycle-safe thread ID's and when thread stack gets freed?

Does the stack reserved/commited for a thread get freed when
the thread terminates
the thread object is destroyed
(i.e. the thread is terminated and all handles to the thread are closed)
?
More broadly, are there significant resources associated with a thread that has terminated, but still exists since there are valid handles to it?
Reason: I need to modify a kind of "scoped singleton", so it doesn't return a single object, but a per-thread object. I cannot rely on thread creation/termination notices, much less on process-wide ones.
At the moment, I store the objects in a map<ThreadID, Object>, with a cache cleanup policy that's suitable for my application. To protect myself from the OS "recycling" thread ID's, I keep an handle to the thread open. (Rec
A side effect would be holding open handles to long-terminated threads in some corner cases.
According to "Windows VIA C/C++" by Richter and Nasarre (A must-have book for any C++ Windwos programmer) p.154:
Terminating a Thread
A thread can be terminated in four
ways:
The thread function returns. (This is highly recommended.)
The thread kills itself by calling the ExitThread function. (Avoid this
method.)
A thread in the same process or in another one calls the TerminateThread
function. (Avoid this method.)
The process containing the thread terminates. (Avoid this method.)
The Thread Function Returns
You should always design your thread
functions so that they return when you
want the thread to terminate. This is
the only way to guarantee that all
your thread's resources are cleaned up
properly.
Having your thread function return
ensures the following:
All C++ objects created in your thread function will be destroyed
properly via their destructors.
The operating system will properly free the memory used by the thread's
stack.
The system will set the thread's exit code (maintained in the thread's
kernel object) to your thread
function's return value.
The system will decrement the usage count of the thread's kernel object.
The ExitThread Function
You can force your thread to terminate by having it call ExitThread:
VOID ExitThread(DWORD dwExitCode);
This function terminates the thread
and causes the operating system to
clean up all the operating system
resources that were used by the
thread. However, your C/C++ resources
(such as C++ class objects) will not
be destroyed. For this reason, it is
much better to simply return from your
thread function instead of calling
ExitThread yourself.
Of course, you use ExitThread's
dwExitCode parameter to tell the
system what to set the thread's exit
code to. The ExitThread function does
not return a value because the thread
has terminated and cannot execute any
more code.
Note The recommended way to have a
thread terminate is by having its
thread function simply return (as
described in the previous section).
However, if you use the method
described in this section, be aware
that the ExitThread function is the
Windows function that kills a thread.
If you are writing C/C++ code, you
should never call ExitThread. Instead,
you should use the C++ run-time
library function _endthreadex. If you
do not use Microsoft's C++ compiler,
your compiler vendor will have its own
alternative to ExitThread. Whatever
this alternative is, you must use it.
The TerminateThread Function
A call to
TerminateThread also kills a thread:
BOOL TerminateThread( HANDLE
hThread, DWORD dwExitCode);
Unlike ExitThread, which always kills
the calling thread, TerminateThread
can kill any thread. The hThread
parameter identifies the handle of the
thread to be terminated. When the
thread terminates, its exit code
becomes the value you passed as the
dwExitCode parameter. Also, the
thread's kernel object has its usage
count decremented.
Note The TerminateThread function is
asynchronous. That is, it tells the
system that you want the thread to
terminate but the thread is not
guaranteed to be killed by the time
the function returns. If you need to
know for sure that the thread has
terminated, you might want to call
WaitForSingleObject or a similar function,
passing the handle of the thread.
A well-designed application never uses
this function because the thread being
terminated receives no notification
that it is dying. The thread cannot
clean up properly, and it cannot
prevent itself from being killed.
Note When a thread dies by returning
or calling ExitThread, the stack for
the thread is destroyed. However, if
TerminateThread is used, the system
does not destroy the thread's stack
until the process that owned the
thread terminates. Microsoft purposely
implemented TerminateThread in this
way. If other still-executing threads
were to reference values on the
forcibly killed thread's stack, these
other threads would raise access
violations. By leaving the killed
thread's stack in memory, other
threads can continue to execute just
fine.
In addition, dynamic-link libraries
(DLLs) usually receive notifications
when a thread is terminating. If a
thread is forcibly killed with
TerminateThread, however, the DLLs do
not receive this notification, which
can prevent proper cleanup.
When a Thread Terminates
The following actions occur when a
thread terminates:
All User object handles owned by the
thread are freed. In Windows, most
objects are owned by the process
containing the thread that creates the
objects. However, a thread owns two
User objects: windows and hooks. When
a thread dies, the system
automatically destroys any windows and
uninstalls any hooks that were created
or installed by the thread. Other
objects are destroyed only when the
owning process terminates.
The thread's exit code changes from
STILL_ACTIVE to the code passed to
ExitThread or TerminateThread.
The state of the thread kernel object
becomes signaled.
If the thread is the last active
thread in the process, the system
considers the process terminated as
well.
The thread kernel object's usage count
is decremented by 1.
When a thread terminates, its
associated thread kernel object
doesn't automatically become freed
until all the outstanding references
to the object are closed.
Once a thread is no longer running,
there isn't much any other thread in
the system can do with the thread's
handle. However, these other threads
can call GetExitCodeThread to check
whether the thread identified by
hThread has terminated and, if it has,
determine its exit code:
BOOL GetExitCodeThread( HANDLE
hThread, PDWORD pdwExitCode);
The exit code value is returned in the
DWORD pointed to by pdwExitCode. If
the thread hasn't terminated when
GetExitCodeThread is called, the
function fills the DWORD with the
STILL_ACTIVE identifier (defined as
0x103). If the function is successful,
TRUE is returned.
Maybe you should use pthread_getspecific, pthread_setspecific and pthread_key_create to manage your per thread singleton.

Resources