Home > QNX > Unblock Handler

Unblock Handler

September 21st, 2007 Leave a comment Go to comments

I had fun writing my first unblock handler in a resource manager. unblock handling is required when clients are currently blocked on a resource manager service and are requesting to be unblocked because of being hit by a signal or other reasons. The kernel will detect that they’d like be unblocked and will send a pulse to the server passing the rcvid and ocb that need to be unblocked and that resource manager can decide what to do with it.

So the reason I was adding this was to support timeouts on the API. This is relatively easy to do from a client API:

struct sigevent api_timeout_event;
api_timeout_event.sigev_notify = SIGEV_UNBLOCK;
api_timeout_value = 100 * 1000 * 1000;  // 100 ms
TimerTimeout(CLOCK_REALTIME, _NTO_TIMEOUT_SEND | _NTO_TIMEOUT_REPLY, &api_timeout_event, &api_timeout_value, &hdl->api_timeout_left);
rc = MsgSend(fd, &msg, sizeof msg.to, NULL, 0);
if (rc == -1 && errno == EINTR) {
	fprintf(stderr, "Interrupted!\n");
}

Supporting this in a server is more difficult. The server is already in the middle of processing the request, potentially
already blocked itself. Ideally we could cancel the request but sometimes that isn’t possible.

Lets just say you can, your unblock handler could be as simple as:

int io_unblock(resmgr_context_t *ctp, io_pulse_t *msg, RESMGR_OCB_T *ocb)
{
	struct _msg_info	info;

	if (MsgInfo(ctp->rcvid, &info) != -1 && (info.flags & _NTO_MI_UNBLOCK_REQ)) {
		cancellation_flag = true;  // other code knows to check this periodically and cancel
		                           // if it's set.
	}
	return(_RESMGR_NOREPLY);
}

It’s important to do that MsgInfo check first because its possible that since getting the pulse the client may have already been replied to.

For the full docs on the QNX site visit http://www.qnx.com/developers/docs/6.3.0SP3/neutrino/prog/resmgr.html#HANDLING_UNBLOCKING

Categories: QNX Tags: