pthread_cancel ()

Hi, all:

We are having a problem like this:

When a thread is in reply_blocked, pthread_cancel () can not cancel it
immediately (it seems that the thread can not be cancelled until it becomes
ready, although pthread_cancel () returns immediately with EOK), does it
mean that reply_blocked is not a cancellation point?

However, we do need to cancel the thread (like above)immediately whenever we
want to do that, otherwise our real time performance will be degraded. Any
help is well appreciated on the following questions:

  1. Is there a way to unblock a thread when it is in reply_blocked or other
    kinds of blocked? or whatever methods which can enable the cancellation
    action happen immediately?
  2. What is the easiest way for me to check (in my code) if my thread is
    blocked or not?

Many thanks!

Xuedong

Xuedong Chen <Xuedong.Chen@igt.com> wrote:

Hi, all:

We are having a problem like this:

When a thread is in reply_blocked, pthread_cancel () can not cancel it
immediately (it seems that the thread can not be cancelled until it becomes
ready, although pthread_cancel () returns immediately with EOK), does it
mean that reply_blocked is not a cancellation point?

Not exactly, it depends on the server, and whether it has set the
_NTO_CHF_UNBLOCK flag. Check the docs for ChannelCreate() and that
flag, but mentally change the sentence that says, “The sending thread
may be unblocked because of a signal or a kernel timeout.” to, “The
sending thread may be unblocked because of a signal, thread cancellation or a
kernel timeout.”

However, we do need to cancel the thread (like above)immediately whenever we
want to do that, otherwise our real time performance will be degraded. Any
help is well appreciated on the following questions:

  1. Is there a way to unblock a thread when it is in reply_blocked or other
    kinds of blocked? or whatever methods which can enable the cancellation
    action happen immediately?

No, this is under control of the server. The server may need to cleanup
or otherwise handle in a sensible way the unblocking of the REPLY blocked
client – either by allowing the request to succeed or failing it immediately.

So, what process/server is your thread REPLY-blocked on? Is that one you
have written or a system process? If it is one that you have written,
are you handling unblock pulses in a timely manner?

  1. What is the easiest way for me to check (in my code) if my thread is
    blocked or not?

Well, a thread can’t check to see if it is blocked, because if blocked,
it can’t do any checking (kind of by definition).

For another thread, you can get a snapshot, but it could be out of date
as soon as you’ve checked it.

-David

QNX Training Services
dagibbs@qnx.com

Thanks.

  1. Will OS send an unblock pulse to the Server when the requesting thread is
    being cancelled by pthread_cancel ()?

  2. After the server receives an unblock pulse, how can I set up to unblock
    the requesting thread?

Xuedong


“David Gibbs” <dagibbs@qnx.com> wrote in message
news:9n8ekb$rps$2@nntp.qnx.com

Xuedong Chen <> Xuedong.Chen@igt.com> > wrote:
Hi, all:

We are having a problem like this:

When a thread is in reply_blocked, pthread_cancel () can not cancel it
immediately (it seems that the thread can not be cancelled until it
becomes
ready, although pthread_cancel () returns immediately with EOK), does it
mean that reply_blocked is not a cancellation point?

Not exactly, it depends on the server, and whether it has set the
_NTO_CHF_UNBLOCK flag. Check the docs for ChannelCreate() and that
flag, but mentally change the sentence that says, “The sending thread
may be unblocked because of a signal or a kernel timeout.” to, “The
sending thread may be unblocked because of a signal, thread cancellation
or a
kernel timeout.”

However, we do need to cancel the thread (like above)immediately
whenever we
want to do that, otherwise our real time performance will be degraded.
Any
help is well appreciated on the following questions:

  1. Is there a way to unblock a thread when it is in reply_blocked or
    other
    kinds of blocked? or whatever methods which can enable the cancellation
    action happen immediately?

No, this is under control of the server. The server may need to cleanup
or otherwise handle in a sensible way the unblocking of the REPLY blocked
client – either by allowing the request to succeed or failing it
immediately.

So, what process/server is your thread REPLY-blocked on? Is that one you
have written or a system process? If it is one that you have written,
are you handling unblock pulses in a timely manner?

  1. What is the easiest way for me to check (in my code) if my thread is
    blocked or not?

Well, a thread can’t check to see if it is blocked, because if blocked,
it can’t do any checking (kind of by definition).

For another thread, you can get a snapshot, but it could be out of date
as soon as you’ve checked it.

-David

QNX Training Services
dagibbs@qnx.com

Xuedong Chen <Xuedong.Chen@igt.com> wrote:

Thanks.

  1. Will OS send an unblock pulse to the Server when the requesting thread is
    being cancelled by pthread_cancel ()?

Yes.

  1. After the server receives an unblock pulse, how can I set up to unblock
    the requesting thread?

Two main choices: MsgReply() or MsgError().

If your server has not replied to the client, you need to have saved
the client’s rcvid. In the unblock pulse, the pulse.value.sival_int
is the rcvid that corresponds to the client that is trying to be blocked.

On the server side, you need to either cleanup the unfinished operation
in whatever way makes more sense for the server (roll-back, partial
finish, partial reply, or whatever) and either MsgReply() with appropriate
results (again, might be partial data, failure notification, etc) or
MsgError(), chosing an appropriate errno value – in this case either
EINTR or ETIMEDOUT are reasonable choices, with EINTR being probably the
best choice.

-David

QNX Training Services
dagibbs@qnx.com

“David Gibbs” <dagibbs@qnx.com> wrote in message
news:9n8i9m$127$1@nntp.qnx.com

Xuedong Chen <> Xuedong.Chen@igt.com> > wrote:
Thanks.

  1. Will OS send an unblock pulse to the Server when the requesting
    thread is
    being cancelled by pthread_cancel ()?

Yes.

  1. After the server receives an unblock pulse, how can I set up to
    unblock
    the requesting thread?

Two main choices: MsgReply() or MsgError().

If your server has not replied to the client, you need to have saved
the client’s rcvid. In the unblock pulse, the pulse.value.sival_int
is the rcvid that corresponds to the client that is trying to be blocked.

On the server side, you need to either cleanup the unfinished operation
in whatever way makes more sense for the server (roll-back, partial
finish, partial reply, or whatever) and either MsgReply() with appropriate
results (again, might be partial data, failure notification, etc) or
MsgError(), chosing an appropriate errno value – in this case either
EINTR or ETIMEDOUT are reasonable choices, with EINTR being probably the
best choice.

-David

QNX Training Services
dagibbs@qnx.com

Thanks, Dave.

Xuedong
“David Gibbs” <dagibbs@qnx.com> wrote in message
news:9n8i9m$127$1@nntp.qnx.com

Xuedong Chen <> Xuedong.Chen@igt.com> > wrote:
Thanks.

  1. Will OS send an unblock pulse to the Server when the requesting
    thread is
    being cancelled by pthread_cancel ()?

Yes.

  1. After the server receives an unblock pulse, how can I set up to
    unblock
    the requesting thread?

Two main choices: MsgReply() or MsgError().

If your server has not replied to the client, you need to have saved
the client’s rcvid. In the unblock pulse, the pulse.value.sival_int
is the rcvid that corresponds to the client that is trying to be blocked.

On the server side, you need to either cleanup the unfinished operation
in whatever way makes more sense for the server (roll-back, partial
finish, partial reply, or whatever) and either MsgReply() with appropriate
results (again, might be partial data, failure notification, etc) or
MsgError(), chosing an appropriate errno value – in this case either
EINTR or ETIMEDOUT are reasonable choices, with EINTR being probably the
best choice.

-David

QNX Training Services
dagibbs@qnx.com

Xuedong Chen <Xuedong.Chen@igt.com> wrote:

Thanks, Dave.

You’re quite welcome.

Hope things are going well down there in the land of hot & dry summer.

-David


QNX Training Services
dagibbs@qnx.com

Where can I find more information about rcvid? How is rcvid formed?
Different threads in the same client process should have the same rcvid or
different ones? rcvid should have nothing to do with Server, right?

If Server need to understand which requesting thread is associated with a
pulse, what I need to do is to compare the rcvid in the pulse with rcvid
(s) which I buffered when I received the message requests?

Thanks,

Xuedong


“Xuedong Chen” <Xuedong.Chen@IGT.com> wrote in message
news:9n8l6a$7i0$1@inn.qnx.com

“David Gibbs” <> dagibbs@qnx.com> > wrote in message
news:9n8i9m$127$> 1@nntp.qnx.com> …
Xuedong Chen <> Xuedong.Chen@igt.com> > wrote:
Thanks.

  1. Will OS send an unblock pulse to the Server when the requesting
    thread is
    being cancelled by pthread_cancel ()?

Yes.

  1. After the server receives an unblock pulse, how can I set up to
    unblock
    the requesting thread?

Two main choices: MsgReply() or MsgError().

If your server has not replied to the client, you need to have saved
the client’s rcvid. In the unblock pulse, the pulse.value.sival_int
is the rcvid that corresponds to the client that is trying to be
blocked.

On the server side, you need to either cleanup the unfinished operation
in whatever way makes more sense for the server (roll-back, partial
finish, partial reply, or whatever) and either MsgReply() with
appropriate
results (again, might be partial data, failure notification, etc) or
MsgError(), chosing an appropriate errno value – in this case either
EINTR or ETIMEDOUT are reasonable choices, with EINTR being probably the
best choice.

-David

QNX Training Services
dagibbs@qnx.com

One more question, Dave, what will happen if I didn’t do any clean up work
before unblcking the requesting thread, I mean in terms of messaging thing
(forget my specific job), for example, the logic in Server side:

void * Server::handleJob1Thread
{
// Do the real job, take significant time here.

// Job is done, reply a message.
MsgReply (…);

//…
}

When unblocking the requesting thread, I didn’t stop the associating
working thread within the Server, so this thread will keep going, and when
the job is done, it will reply a message which should not be sent. What
problem we may have here?

Thanks.

Xuedong


“David Gibbs” <dagibbs@qnx.com> wrote in message
news:9n8i9m$127$1@nntp.qnx.com

Xuedong Chen <> Xuedong.Chen@igt.com> > wrote:
Thanks.

  1. Will OS send an unblock pulse to the Server when the requesting
    thread is
    being cancelled by pthread_cancel ()?

Yes.

  1. After the server receives an unblock pulse, how can I set up to
    unblock
    the requesting thread?

Two main choices: MsgReply() or MsgError().

If your server has not replied to the client, you need to have saved
the client’s rcvid. In the unblock pulse, the pulse.value.sival_int
is the rcvid that corresponds to the client that is trying to be blocked.

On the server side, you need to either cleanup the unfinished operation
in whatever way makes more sense for the server (roll-back, partial
finish, partial reply, or whatever) and either MsgReply() with appropriate
results (again, might be partial data, failure notification, etc) or
MsgError(), chosing an appropriate errno value – in this case either
EINTR or ETIMEDOUT are reasonable choices, with EINTR being probably the
best choice.

-David

QNX Training Services
dagibbs@qnx.com

Xuedong Chen <Xuedong.Chen@igt.com> wrote:

Where can I find more information about rcvid? How is rcvid formed?
Different threads in the same client process should have the same rcvid or
different ones? rcvid should have nothing to do with Server, right?

You should not know “how the rcvid is formed”. It is only an int
to you. Each rcvid gurenteed that it is represent an “unique” MsgSend().
So, if different threads send though same connect, the server got
different “rcvid”.

If Server need to understand which requesting thread is associated with a
pulse, what I need to do is to compare the rcvid in the pulse with rcvid
(s) which I buffered when I received the message requests?

Yes, and there are more complicate race conditions.

In theroy, you only receive UNBLOCK pulse only if the client blocking on you.
So the rcvid in pulse should always matching one of your “buffered” rcvid.

However, pulse can be queued and delayed. So, if a client blocking on you,
and somebody “ctrl-c” it twice, you will receive 2 Unblock pulse, and in
that case, the second pulse have a rcvid not in your buffered rcvid.

Now the weired case is “if the unblock happened before you can receive it”,
or (in above case), after you MsgReply()/MsgError() back upon the first
pulse, the client bump up its’ priority and MsgSend() you again, before
you can process the second pulse…

-xtang

“Xuedong Chen” <> Xuedong.Chen@IGT.com> > wrote in message
news:9n8l6a$7i0$> 1@inn.qnx.com> …

“David Gibbs” <> dagibbs@qnx.com> > wrote in message
news:9n8i9m$127$> 1@nntp.qnx.com> …
Xuedong Chen <> Xuedong.Chen@igt.com> > wrote:
Thanks.

  1. Will OS send an unblock pulse to the Server when the requesting
    thread is
    being cancelled by pthread_cancel ()?

Yes.

  1. After the server receives an unblock pulse, how can I set up to
    unblock
    the requesting thread?

Two main choices: MsgReply() or MsgError().

If your server has not replied to the client, you need to have saved
the client’s rcvid. In the unblock pulse, the pulse.value.sival_int
is the rcvid that corresponds to the client that is trying to be
blocked.

On the server side, you need to either cleanup the unfinished operation
in whatever way makes more sense for the server (roll-back, partial
finish, partial reply, or whatever) and either MsgReply() with
appropriate
results (again, might be partial data, failure notification, etc) or
MsgError(), chosing an appropriate errno value – in this case either
EINTR or ETIMEDOUT are reasonable choices, with EINTR being probably the
best choice.

-David

QNX Training Services
dagibbs@qnx.com

Xuedong Chen <Xuedong.Chen@igt.com> wrote:

One more question, Dave, what will happen if I didn’t do any clean up work
before unblcking the requesting thread, I mean in terms of messaging thing
(forget my specific job), for example, the logic in Server side:

void * Server::handleJob1Thread
{
// Do the real job, take significant time here.

// Job is done, reply a message.
MsgReply (…);

//…
}

When unblocking the requesting thread, I didn’t stop the associating
working thread within the Server, so this thread will keep going, and when
the job is done, it will reply a message which should not be sent. What
problem we may have here?

In unblocking process, you set a flag “THIS JOB IS CANCELED”, and MsgReply()/
MsgError() the client to let him go.

Your “real work thread”, should either check the flag from time to time,
or at least, before MsgReply(), and throw away things if job is canceled.

You must make sure, if the client go away, and MsgSend() you again,
he get another “job structure”. Otherwise, you might just clear
the CANCELED flag, and the work thread endup MsgReply() to a wrong
MsgSend().

-xtang


Thanks.

Xuedong



“David Gibbs” <> dagibbs@qnx.com> > wrote in message
news:9n8i9m$127$> 1@nntp.qnx.com> …
Xuedong Chen <> Xuedong.Chen@igt.com> > wrote:
Thanks.

  1. Will OS send an unblock pulse to the Server when the requesting
    thread is
    being cancelled by pthread_cancel ()?

Yes.

  1. After the server receives an unblock pulse, how can I set up to
    unblock
    the requesting thread?

Two main choices: MsgReply() or MsgError().

If your server has not replied to the client, you need to have saved
the client’s rcvid. In the unblock pulse, the pulse.value.sival_int
is the rcvid that corresponds to the client that is trying to be blocked.

On the server side, you need to either cleanup the unfinished operation
in whatever way makes more sense for the server (roll-back, partial
finish, partial reply, or whatever) and either MsgReply() with appropriate
results (again, might be partial data, failure notification, etc) or
MsgError(), chosing an appropriate errno value – in this case either
EINTR or ETIMEDOUT are reasonable choices, with EINTR being probably the
best choice.

-David

QNX Training Services
dagibbs@qnx.com

Thanks.

So what you suggested is that we should stop 'MsgReply (…) in our code
when the requesting thread is unblock? Otherwise it is always a risk?

Xuedong

“Xiaodan Tang” <xtang@qnx.com> wrote in message
news:9nallh$aip$2@nntp.qnx.com

Xuedong Chen <> Xuedong.Chen@igt.com> > wrote:
One more question, Dave, what will happen if I didn’t do any clean up
work
before unblcking the requesting thread, I mean in terms of messaging
thing
(forget my specific job), for example, the logic in Server side:

void * Server::handleJob1Thread
{
// Do the real job, take significant time here.

// Job is done, reply a message.
MsgReply (…);

//…
}

When unblocking the requesting thread, I didn’t stop the associating
working thread within the Server, so this thread will keep going, and
when
the job is done, it will reply a message which should not be sent. What
problem we may have here?

In unblocking process, you set a flag “THIS JOB IS CANCELED”, and
MsgReply()/
MsgError() the client to let him go.

Your “real work thread”, should either check the flag from time to time,
or at least, before MsgReply(), and throw away things if job is canceled.

You must make sure, if the client go away, and MsgSend() you again,
he get another “job structure”. Otherwise, you might just clear
the CANCELED flag, and the work thread endup MsgReply() to a wrong
MsgSend().

-xtang


Thanks.

Xuedong


“David Gibbs” <> dagibbs@qnx.com> > wrote in message
news:9n8i9m$127$> 1@nntp.qnx.com> …
Xuedong Chen <> Xuedong.Chen@igt.com> > wrote:
Thanks.

  1. Will OS send an unblock pulse to the Server when the requesting
    thread is
    being cancelled by pthread_cancel ()?

Yes.

  1. After the server receives an unblock pulse, how can I set up to
    unblock
    the requesting thread?

Two main choices: MsgReply() or MsgError().

If your server has not replied to the client, you need to have saved
the client’s rcvid. In the unblock pulse, the pulse.value.sival_int
is the rcvid that corresponds to the client that is trying to be
blocked.

On the server side, you need to either cleanup the unfinished operation
in whatever way makes more sense for the server (roll-back, partial
finish, partial reply, or whatever) and either MsgReply() with
appropriate
results (again, might be partial data, failure notification, etc) or
MsgError(), chosing an appropriate errno value – in this case either
EINTR or ETIMEDOUT are reasonable choices, with EINTR being probably
the
best choice.

-David

QNX Training Services
dagibbs@qnx.com