Write() blocked on /devb/umass

Hi all,

I am back with a new query.
I have an application which has multiple threads performing write() to USB drive simultaneously.
May be around 32 writer threads will be there and they are getting write requests from a list.
There will always be (KB or MB sized) writes going on. At the time of stopping the application, writer threads need to complete
their pending writes in the list and get terminated.

At an instant, I need to stop the application and I send signal to these threads. When the writers started
performing pending write operations in the list, i just removed the USB drive.
Now I have a strange observation. The writer threads are blocked on /devb/umass. The signal is not hitting
the writer threads and also I am not getting error in write() call. The application is not stopped because the writers are not stopped.
How can I stop the writer threads gracefully? I mean, if the USB is removed after stop, let them exit without
completing pending writes. Could you please share your thoughts on this?

Thanks,
Lullaby

You are describing two incompatible objectives. 1) Stopping at an instant, 2) Stopping gracefully. Which is it that you want?

The signal is probably working, just not in the way you suspect. What you are seeing is a special feature of QNX that you will need to understand.

I/O from a client in QNX involves sending a message to a resource manager. If the client gets a signal while reply blocked, the message is handled in a special way. The purpose is to inform the resource manager so that it can decide whether to complete the I/O request or terminate it immediately. The way this happens is that the resource manager gets a pulse. It can then decide to prematurely reply to the client, or ignore the pulse and finish the I/O. The client is hung until one of these occurs.

Since you are doing multiple large writes from your process, I suspect that the resource manager is trying to finish the I/O before replying. So in this case, the resource manager is complying with your desire to stop gracefully, but it can’t do it immediately.

Use the systeme profiler to make sure the signal does hit the thread.

Hi all,

What I expect from the application is that:-

  1. If the application is stopped by the user, then the application needs all the pending writes to be completed and exit gracefully.
    (if the device is connected and accessible).
  2. If the application is stopped by the user, application starts to complete its pending writes. At that moment, if I am removing my
    USB drive, I expect that my application should stop immediately without waiting for pending writes completion since
    the device is not available.
    So I expect when the pending writes is in progress on the writer thread, if a signal is hit(intimating the user needs to stop the application) and the USB drive is removed, I need the write() call to return with an error code and thus exit the writer threads and application itself.

What I understood from your reply is that:- the write() call is hung waiting for the resource manager’s reply regarding terminate and resource manager is busy trying to complete the write on USB drive before the reply is dispatched back to write() call. Since the USB drive is removed, it can’t complete the write operation and it won’t reply to client.

So my query is that:- Didn’t the resource manager get an intimation if the device is removed while the write is in progress? If so, it won’t get blocked, right?

I have also modified the code with O_NONBLOCK flag in open() call. Still the problem is there in the same situation.

Thanks,
Lullaby

Now you are asking a question about the behavior of the driver. I can’t respond to that without testing. I agree that the driver should probably discover that the USB has been removed and that the write will not complete, and it should report back so your process can die. If that is not happening, you probably will need to discuss this with QNX.

There is however a work around. You can detect insertion and removal of the USB yourself. You could set things up so that if the USB drive is removed, you programatically kill the driver.

Ok. Thank you.