I have a synchronization issue that I can’t come up with a
good solution for. Since this appears to be somewhat endemic
to USB and resmgr framework, I was wondering if there is a
Assumptions (any of these invalid ?):
resmgr_detach will not block when a io callback is
active, even when _RESMGR_DETACH_ALL flag is specified.
resmgr_detach does block for connect (but not IO)
The usbd code that calls the user supplied removal callback
deallocates the memory that was specified during the call
to usbd_attach() after calling the clients removal
OK, here is the scenerio.
One of my client read threads (io_read callback), is
sleeping on some buffers that are allocated to pointers
that reside in the area provided to usbd_attach.
The USB cable is removed.
The removal callback is dispatched.
The removal callback does a broadcast on the addresses
that the client thread (from 1) is sleeping on; then…
resmgr_detach is called (with the _RESMGR_DETACH_ALL flag
set). This doesn’t block (assumption 1).
Due to the fact that the USB DDK client thread that
executes the removal callback is of a higher priority than
the client priority driver threads of the io_* callbacks,
the removal thread frees all the memory associated with
the client buffers, and returns.
The USB DDK client library then frees the entire structure
that was reserved with the usbd_attach() call.
Client thread now wakes up (from the broadcast in 4), and
checks a status field inside the area allocated via
usbd_attach(). Here is the problem. This area is no
longer valid as it has been freed.
How does one get around this issue cleanly ? It seems to me
that if resmgr_detach, did block (due to the fact that an IO
callback was active), then everything would be cool, since
the broadcast would guarantee that the io thread would awake
before the removal thread had smoked the memory. It would
check that status field in the (still valid) memory area,
and return immediately with an error (since a flag there
would indicate the the device had been removed).
Of course, I could come up with some scheme of my own to do
this, but I guess I’m not quite sure why outstanding IO
operations do not cause resmgr_detach to block until they
have completed (with the responsibility of client code to
insure that the operations do complete - in my case because
I deliberately unblock them in the removal callback).