Robert Shearman R.J.Shearman@warwick.ac.uk writes:
This has been hanging around in my tree for a while. This is useful for RPC and for eventually implementing QueueUserWorkItem.
Changelog: Implement I/O completion ports
You should use the normal waiting mechanisms, instead of creating a new type of waiting request which requires exporting a bunch of private functions. This means there should be only a single remove_io_completion request, and the wait should be done with a standard WaitForSingleObject.
-----Original Message----- From: Alexandre Julliard [mailto:julliard@winehq.com] Sent: 11 November 2003 21:03 To: Robert Shearman Cc: wine-devel@winehq.org Subject: Re: I/O Completion Ports Implementation
Robert Shearman R.J.Shearman@warwick.ac.uk writes:
This has been hanging around in my tree for a while. This is
useful for RPC
and for eventually implementing QueueUserWorkItem.
Changelog: Implement I/O completion ports
You should use the normal waiting mechanisms, instead of creating a new type of waiting request which requires exporting a bunch of private functions. This means there should be only a single remove_io_completion request, and the wait should be done with a standard WaitForSingleObject.
WaitForSingleObject(hIoCompletion, INFINITE) returns straight away with WAIT_OBJECT_0 on Windows. Using it would break this behaviour (which of course any sane apps would not depend on). I'd rather have a completely correct implementation now with minor changes. (Although I could move the Nt* functions into sync.c to save 'exporting' wait_reply).
In short, the way I've done it works and shouldn't have to be changed later.
Rob
"Robert Shearman" R.J.Shearman@warwick.ac.uk writes:
WaitForSingleObject(hIoCompletion, INFINITE) returns straight away with WAIT_OBJECT_0 on Windows. Using it would break this behaviour (which of course any sane apps would not depend on).
I must be missing something, but I don't see how your code can do that. You are waiting on the handle anyway so the behavior will be the same if you use WaitForSingleObject. If that is not supposed to work then you need to create another object to wait on, and that's true whether you use WaitForSingleObject or not.
-----Original Message----- From: Alexandre Julliard [mailto:julliard@winehq.com] Sent: 12 November 2003 00:06 To: Robert Shearman Cc: wine-devel@winehq.org Subject: Re: I/O Completion Ports Implementation
"Robert Shearman" R.J.Shearman@warwick.ac.uk writes:
WaitForSingleObject(hIoCompletion, INFINITE) returns straight away with WAIT_OBJECT_0 on Windows. Using it would break this behaviour (which of course any sane apps would not depend on).
I must be missing something, but I don't see how your code can do that.
In remove_io_completion:
+ port->satisfied = 0; /* don't abandon wait on the port */ + select_on(1, req->cookie, &req->handle, SELECT_TIMEOUT, &req->timeout); + port->satisfied = 1; /* abandon any waits on the port immediately */
Maybe it's a bit of a hack, but I assume this behaviour won't change any time soon: select_on only checks if the object is satisfied when it is first called and waits for manual notification that the object has been satisfied once the select_on call has succeeded. Therefore I set the flag to say that it isn't satisfied before calling select_on so that the select_on call will actually make the thread sleep and then set the flag back afterwards so that the behaviour is present of returning immediately because it is satisfied.
You are waiting on the handle anyway so the behavior will be the same if you use WaitForSingleObject. If that is not supposed to work then you need to create another object to wait on, and that's true whether you use WaitForSingleObject or not.
This is what I originally did, but I ended up having to duplicate functionality from most of server/thread.c to achieve it. I thought this new way would be somewhat cleaner (and the patch is indeed a lot smaller).
Rob
"Robert Shearman" R.J.Shearman@warwick.ac.uk writes:
In remove_io_completion:
port->satisfied = 0; /* don't abandon wait on the port */
select_on(1, req->cookie, &req->handle, SELECT_TIMEOUT,
&req->timeout);
port->satisfied = 1; /* abandon any waits on the port immediately
*/
Maybe it's a bit of a hack, but I assume this behaviour won't change any time soon: select_on only checks if the object is satisfied when it is first called and waits for manual notification that the object has been satisfied once the select_on call has succeeded. Therefore I set the flag to say that it isn't satisfied before calling select_on so that the select_on call will actually make the thread sleep and then set the flag back afterwards so that the behaviour is present of returning immediately because it is satisfied.
OK, I guess you meant to use the signaled() method instead of satisfied() (the satisfied method is used to cleanup after the wait has succeeded, so it's not what you want here). But it still wouldn't work properly, since it's possible that we'll check the wait condition again later on while the thread is sleeping (for instance if the thread gets suspended) and it would then return a spurious signaled condition. You should really use the proper wait mechanisms instead of trying to subvert them that way.
This is what I originally did, but I ended up having to duplicate functionality from most of server/thread.c to achieve it. I thought this new way would be somewhat cleaner (and the patch is indeed a lot smaller).
I don't see why you'd need to duplicate anything. Just create another object, like an event, and return that in remove_io. Then the client can simply do a WaitForSingleObject on the event.
-----Original Message----- From: Alexandre Julliard [mailto:julliard@winehq.com] Sent: 12 November 2003 00:45 To: Robert Shearman Cc: wine-devel@winehq.org Subject: Re: I/O Completion Ports Implementation
"Robert Shearman" R.J.Shearman@warwick.ac.uk writes:
Maybe it's a bit of a hack, but I assume this behaviour won't change any time soon: select_on only checks if the object is satisfied
when it is first
called and waits for manual notification that the object has
been satisfied
once the select_on call has succeeded. Therefore I set the flag
to say that
it isn't satisfied before calling select_on so that the
select_on call will
actually make the thread sleep and then set the flag back
afterwards so that
the behaviour is present of returning immediately because it is
satisfied.
OK, I guess you meant to use the signaled() method instead of satisfied() (the satisfied method is used to cleanup after the wait has succeeded, so it's not what you want here). But it still wouldn't work properly, since it's possible that we'll check the wait condition again later on while the thread is sleeping (for instance if the thread gets suspended) and it would then return a spurious signaled condition. You should really use the proper wait mechanisms instead of trying to subvert them that way.
Yes, you are right. Satisfied only works in the SELECT_ALL case.
This is what I originally did, but I ended up having to duplicate functionality from most of server/thread.c to achieve it. I
thought this new
way would be somewhat cleaner (and the patch is indeed a lot smaller).
I don't see why you'd need to duplicate anything. Just create another object, like an event, and return that in remove_io. Then the client can simply do a WaitForSingleObject on the event.
Ok, I hadn't thought of doing it that way :)
Rob