Unblocking with serial driver

What I want to do is make sure that my server process gets a pulse to
unblock a client who is terminating. The server process is the serial
driver in this case. I am not sure if the server is set up to receive a
pulse when the client is terminating. The documentation states that the
_NTO_CHF_UNBLOCK flag needs to be set when ChannelCreate is called. I have
searched the source code for the serial driver and did not see ChannelCreate
anywhere. Is there some other operation to set this flag?

I had also read that name_attach sets this flag also. The only “attach”
function call was pulse_attach. The documentation does not say anything
about this flag with regards to pulse_attach. Is this function also setting
the flag? I would like to verify that the serial driver is set up to
receive a pulse to unblock a client when the client terminates.

I have seen a problem where the server process does not unblock a
terminating client. Instead, it replies to it with invalid data which
eventually results in a SIGSEGV. It has been suggested that the server
process did not handle the unblocking properly. I am trying to find an
example on how to unblock a client properly. The serial driver is one such
example that I hope will help me. If there is a better example, please let
me know.

Rex Lam

Rex Lam <Rex.Lam@igt.com> wrote:

What I want to do is make sure that my server process gets a pulse to
unblock a client who is terminating. The server process is the serial
driver in this case. I am not sure if the server is set up to receive a
pulse when the client is terminating. The documentation states that the
_NTO_CHF_UNBLOCK flag needs to be set when ChannelCreate is called. I have
searched the source code for the serial driver and did not see ChannelCreate
anywhere. Is there some other operation to set this flag?

I had also read that name_attach sets this flag also. The only “attach”
function call was pulse_attach. The documentation does not say anything
about this flag with regards to pulse_attach. Is this function also setting
the flag? I would like to verify that the serial driver is set up to
receive a pulse to unblock a client when the client terminates.

If you’re doing pulse_attach(), then you must be using the dispatch_
framework – dispatch_block() and dispatch_handler(). You’ll also have
a resmgr_attach() somewhere in there to register your name.

In fact, all resource manager channels have the unblock notification
requested by default – but you don’t get the pulse directly yourself.
What you do, is you write an unblock handler just the way you would write
a IO_WRITE handler. The library gets the unblock pulse, and it kind of
“fakes up” an unblock message and passes it to you that way, along with
the ocb for the client.

To handle it, you (or the already written serial driver code) would
specify one the same place you’re specifying your read & write handlers:

io_funcs.read = my_read;
io_funcs.unblock = my_unblock_hdlr;

Usually what you do in the unblock handler is to call MsgError(rcvid, EINTR)
to fail the client – but if you have partial data you are allowed to reply
with some or all of the data the client requested. (Or, if it is a case
of a write() call, and you’ve only put part of the data out the serial port,
you should reply letting the write call know how many bytes have been
successfully transmitted.)

If your resource manager is multi-threaded, you will also have to worry
about locking the attributes structure in the unblock handler.

I have seen a problem where the server process does not unblock a
terminating client. Instead, it replies to it with invalid data which
eventually results in a SIGSEGV.

Or, it may be that the client naively assumed that a read() of (say)
40K will always return either failure or 40K, and when they got only
8K of data didn’t handle that properly – read() IS allowed to return
less than the requested amount of data.

It has been suggested that the server
process did not handle the unblocking properly.

Hope the above helps,

-David

QNX Training Services
dagibbs@qnx.com

Thanks. That was very helpful.

“David Gibbs” <dagibbs@qnx.com> wrote in message
news:9gt30e$t2m$1@nntp.qnx.com
Rex Lam <Rex.Lam@igt.com> wrote:

What I want to do is make sure that my server process gets a pulse to
unblock a client who is terminating. The server process is the serial
driver in this case. I am not sure if the server is set up to receive a
pulse when the client is terminating. The documentation states that the
_NTO_CHF_UNBLOCK flag needs to be set when ChannelCreate is called. I
have
searched the source code for the serial driver and did not see
ChannelCreate
anywhere. Is there some other operation to set this flag?

I had also read that name_attach sets this flag also. The only “attach”
function call was pulse_attach. The documentation does not say anything
about this flag with regards to pulse_attach. Is this function also
setting
the flag? I would like to verify that the serial driver is set up to
receive a pulse to unblock a client when the client terminates.

If you’re doing pulse_attach(), then you must be using the dispatch_
framework – dispatch_block() and dispatch_handler(). You’ll also have
a resmgr_attach() somewhere in there to register your name.

In fact, all resource manager channels have the unblock notification
requested by default – but you don’t get the pulse directly yourself.
What you do, is you write an unblock handler just the way you would write
a IO_WRITE handler. The library gets the unblock pulse, and it kind of
“fakes up” an unblock message and passes it to you that way, along with
the ocb for the client.

To handle it, you (or the already written serial driver code) would
specify one the same place you’re specifying your read & write handlers:

io_funcs.read = my_read;
io_funcs.unblock = my_unblock_hdlr;

Usually what you do in the unblock handler is to call MsgError(rcvid, EINTR)
to fail the client – but if you have partial data you are allowed to reply
with some or all of the data the client requested. (Or, if it is a case
of a write() call, and you’ve only put part of the data out the serial port,
you should reply letting the write call know how many bytes have been
successfully transmitted.)

If your resource manager is multi-threaded, you will also have to worry
about locking the attributes structure in the unblock handler.

I have seen a problem where the server process does not unblock a
terminating client. Instead, it replies to it with invalid data which
eventually results in a SIGSEGV.

Or, it may be that the client naively assumed that a read() of (say)
40K will always return either failure or 40K, and when they got only
8K of data didn’t handle that properly – read() IS allowed to return
less than the requested amount of data.

It has been suggested that the server
process did not handle the unblocking properly.

Hope the above helps,

-David

QNX Training Services
dagibbs@qnx.com

Rex Lam <Rex.Lam@igt.com> wrote:

Thanks. That was very helpful.

You’re welcome.

-David