Re: User vs. Worker threads
- From: "David J. Craig" <Dave@xxxxxxxxxxxxx>
- Date: Sat, 27 Jan 2007 11:28:13 -0800
There are some drivers that Microsoft releases that use METHOD_NEITHER.
Class.c from classpnp has an IoCtl that uses it. Some FSCTLs use
METHOD_NEITHER and FastFat flags them to be processed synchronously. There
are reasons to do it and most of those 'reasons' may be invalid, but they do
exist. If you develop filters expect that you will have to handle it
however they are done and not as you wish they had been done. I think Don
is correct in that it should be avoided if possible because so few get the
validation and locking code correct.
I do say that using a worker thread in the context of a user process is a
valid option. As with all design decisions the implications of doing it
that way should be examined.
"anton bassov" <soviet_bloke@xxxxxxxxxxx> wrote in message
news:1169895931.550504.152700@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
David,
There is one addition: Use the NtCurrentProcess() macro to specify the
current process.
Which is just a (HANDLE)-1, i.e. a pseudo-handle that is meant to tell
the system that the target process is the caller process itself.
Things are done this way "since
the beginning of NT world", so that this statement does not refer to
some currently existing feature that was not present 6 years ago...
The design is probably flawed, but for test tools or
proof of concept design, violating a few rules may be a necessary thing.
Yes, I agree that, once in a while, you may want to do things this way
when writing debuggers, analysis tools and other "unsupported"
software. However, such design in itself is rather insecure (in fact,
as METHOD_NEITHER on itself), and, in most cases, the problem can be
just redesigned in more "proper" fashion.
As Don said few months ago, whenever some of his developers wants to
use
METHOD_NEITHER, he requests this developer to write a document,
explaining why, in his opinion, using METHOD_NEITHER in a given
situation
is better than METHOD_BUFFERED or METHOD_DIRECT.
In most cases, after having listed all pros and cons, developers
realize that
METHOD_NEITHER does not offer any significant advantage in a given
situation -
the only "result" of using it is the increased complexity of the code,
due to necessary address validation.....
Anton Bassov
On Jan 27, 7:23 am, "David J. Craig" <D...@xxxxxxxxxxxxx> wrote:
There is one addition: Use the NtCurrentProcess() macro to specify the
current process.
Also in the comments for this function in the Windows 2000 DDK:
Comments
Drivers that create device-dedicated threads call this routine, either
when
they initialize or when I/O requests begin to come in to such a driver's
Dispatch routines. For example, a driver might create such a thread when
it
receives an asynchronous device control request.
PsCreateSystemThread creates a kernel-mode thread that begins a separate
thread of execution within the system. Such a system thread has no TEB or
user-mode context and runs only in kernel mode.
If the input ProcessHandle is NULL, the created thread is associated with
the system process. Such a thread continues running until either the
system
is shut down or the thread terminates itself by calling
PsTerminateSystemThread.
Driver routines that run in a process context other than that of the
system
process should set the OBJ_KERNEL_HANDLE flag within the Attributes
parameter of PsCreateSystemThread before calling it. This restricts the
use
of the handle returned by PsCreateSystemThread to processes running in
kernel mode and thereby prevents an unintended access of this handle by
the
process in whose context the driver is running.
Callers of this routine must be running at IRQL PASSIVE_LEVEL.
END QUOTE
There is the sentence about using OBJ_KERNEL_HANDLE when the context is
not
the system process. This indicates that there may be reasons why a
driver
might need to run a worker thread in a context other than the system
process'. Using events being passed in from user mode that must be
referenced in the user process' address space is one that I have used.
Isolation is good, but sometimes it can't be done. If you had a read or
write and the data buffers are passed in as neither IO, then keeping
process
context is important. The design is probably flawed, but for test tools
or
proof of concept design, violating a few rules may be a necessary thing.
"anton bassov" <soviet_bl...@xxxxxxxxxxx> wrote in
messagenews:1169850660.921916.7500@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
David,
By the term "MSDN" I meant WDK documentation - in my vocabulary the
term MSDN means any official documentation that comes from MSFT.....
All the statements that you made are based upon the description of
'ProcessHandle' parameter in PsCreateSystemThread()' s documentation in
WDK. However, you overlooked the statement that drivers should specify
NULL
as 'ProcessHandle' parameter...
Here is the precise quotation from RTM version of WDK
[begin quote]
ProcessHandle
Specifies an open handle for the process in whose address space the
thread is to be run. The caller's thread must have
PROCESS_CREATE_THREAD access to this process. If this parameter is not
supplied, the thread will be created in the initial system process.
This value should be NULL for a driver-created thread. Use the
NtCurrentProcess macro to specify the current process.
[end quote]
As you can see, the above excerpts seems to contradict itself - on one
hand, it describes 'ProcessHandle' parameter, but on the other hand, it
states that drivers
should specify NULL for it....
Now look at what Windows 2000 DDK says on the subject:
[begin quote]
ProcessHandle
Specifies an open handle for the process in whose address space the
thread is to be run. The caller's thread must have
PROCESS_CREATE_THREAD access to this process. If this parameter is not
supplied, the thread will be created in the initial system process.
This value should be NULL for a driver-created thread.
[end quote]
As you can see, nothing got changed in 6(!!!) years.......
Anton Bassov
On Jan 26, 6:03 pm, "David J. Craig" <D...@xxxxxxxxxxxxx> wrote:
I would suggest reading the WDK docs. Drivers are better documented
there
than in MSDN Library. The WDK docs are more recent than MSDN Library
which
hasn't seen an update since August.
"anton bassov" <soviet_bl...@xxxxxxxxxxx> wrote in
messagenews:1169808621.785277.87870@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
If a driver creates a thread with PsCreateSystemThread() and uses
NULL
then
you are correct.
According to MSDN, this is how drivers are supposed to do
things......
Anton Bassov
On Jan 26, 6:52 am, "David J. Craig" <D...@xxxxxxxxxxxxx> wrote:
1. The internal name on Windows XP Pro SP2 is null. The query
returns a
buffer of all zeroes (binary). The 'System' process name is given
to
PID
4
in the same OS. It has all the worker threads.
If a driver creates a thread with PsCreateSystemThread() and uses
NULL
then
you are correct. If it uses the NtCurrentProcess() macro, it is
created
in
the current caller's process if the thread has
PROCESS_CREATE_THREAD
access
to this process. Any other process ID can be used if the thread
has
that
permission. If you want to have your worker thread reference an
event
passed in from user mode you can give it process access with the
macro
and
it just works.
"anton bassov" <soviet_bl...@xxxxxxxxxxx> wrote in
messagenews:1169789813.832058.157550@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Kevin,
Basically, you got it right. Congratulations!!!! However, a
couple
of
amendments are still needed.
As far as kernel concerned, there are 3 types of threads:
1. Idle threads, i.e. the ones that CPU dispatches when it has no
other
threads to dispatch. Every CPU has its own idle thread.
Collection
of
idle threads is known as a System Idle Process (this is how it is
known
to the Task Manager - its internal name is just System, and its
PID
is
zero). Idle threads cannot get terminated, for understandable
reasons
2. Worker threads. These threads run tasks that are not directly
related to user requests, and, hence, have no user-mode
representation.
"Lazy writer" thread and Balance Set Manager are typical examples
of
worker threads. Collection of worker threads is known as System
Process
(its PID is non-zero). Worker threads cannot be terminated by
external
means, although they can terminate themselves by calling
PsTerminateSystemThread()
3. All threads that are neither worker nor idle ones are referred
to
as
user threads. These threads have their user-mode representation,
and
can get
terminated both externally and upon their own initiative. In
former
case the target thread may get terminated only if it is able to
receive
user-mode APCs
( i.e. the thread is currently in the user mode or in the waiting
state
with 'UserMode' having been specified as WaitMode' parameter to
KeWait... call). Otherwise, the thread will be terminated only
after
it
makes a return to the user mode
If driver creates a thread in the kernel mode with
PsCreateSystemThread(), this thread will be a worker one - it
will
have
no user-mode representation, and run in context of a system
process,
no
matter in which context PsCreateSystemThread() has been made.
However,
as any other thread, it just cannot "execute separate from the
IRQ-driven code" - when interrupt occurs,
it gets processed in context of arbitrary thread, i.e. the one
that
happens to run on the given CPU at the time of interrupt, no
matter
if
this thread is worker or user or idle one....
Anton Bassov
On Jan 26, 3:25 am, "Kevin" <kevi...@xxxxxxxxxxx> wrote:
In case it is a non-MFC question, then:
A "user thread" is a thread that happens to be executing some
arbitrary
thread from some arbitrary process, while in the kernel.
A "worker thread" is a thread created by device driver code in
the
kernel,
to execute separate from the IRQ-driven code.
"William DePalo [MVP VC++]" <willd.no.s...@xxxxxxxx> wrote in
messagenews:uF64Lu9PHHA.1248@xxxxxxxxxxxxxxxxxxxxxxx
"e_yossi" <eyo...@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:33E2CE27-947E-431B-9476-DE87A75A94C0@xxxxxxxxxxxxxxxx
What are the differences between worker threads
and user threads?
To the operating system, the threads in an _application_ are
all
the
same.
MFC's framework makes a distinction between threads which own
windows
and
have message maps and which therefore spin message loops (UI
threads)
and
threads that don't (worker threads). If you need further
information
on
MFC you should repost in one of the MFC groups.
Regards,
Will
www.ivrforbeginners.com-Hidequotedtext -- Show quoted text --
Hide
quoted text -- Show quoted text -- Hide quoted text -- Show
quoted
text -- Hide quoted text -- Show quoted text -
.
- References:
- Re: User vs. Worker threads
- From: William DePalo [MVP VC++]
- Re: User vs. Worker threads
- From: Kevin
- Re: User vs. Worker threads
- From: anton bassov
- Re: User vs. Worker threads
- From: David J. Craig
- Re: User vs. Worker threads
- From: anton bassov
- Re: User vs. Worker threads
- From: David J. Craig
- Re: User vs. Worker threads
- From: anton bassov
- Re: User vs. Worker threads
- From: David J. Craig
- Re: User vs. Worker threads
- From: anton bassov
- Re: User vs. Worker threads
- Prev by Date: Re: Safely removing hardware
- Next by Date: Re: Memory mapped file pages getting cleared when memory overcommi
- Previous by thread: Re: User vs. Worker threads
- Next by thread: attn: tedman - interesting posts - lilko as ejya - (1/1)
- Index(es):
Relevant Pages
|
Loading