[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.programming.threads

poll/pipe/threads problem

Jose Marcio Martins da Cruz

8/5/2004 9:03:00 AM


Hello,

Sorry if you think this isn't the correct group to post this.

I'm writing a program which is has a "pool of workers".

So, there is a thread "polling" with poll(2) a set of file descriptors
to get tasks. When a task is available on some fd, it pass it to a
worker, who handles the task.

When the worker finishes with the task, it shall return to file
descriptor to the "poller" thread in order to put it again at the array
of pollfd data. I do this with a pipe(2) : to awake the poll call, I
write to one end - the other end is one of the file descriptors on the
array of pollfd data.

So, the poll call is waiting on :
- the read end of the pipe
- some number of file descriptors (TCP sockets)

The problem is that this works if I use select(2), but not poll(2).

But I'd really want to use pipe, not select. At least, I'd like to
understand.

And I can't figure out why :

- The worker writes one character on the write end of the pipe;
- The poll call returns with the correct pipe file descriptor.
- the contents of "events" member of the data returned is the same value
I put before the call (POLLIN | POLLPRI)
- the contents of "revents" member of the data returned is "0" - no
event ???
- if I try to read it, the read call gets blocked.

Thanks for any idea

Jose-Marcio




5 Answers

igor

8/5/2004 1:12:00 PM

0

Jose Marcio Martins da Cruz <martins@paris.ensmp.fr> wrote:
>
> Hello,
>
> Sorry if you think this isn't the correct group to post this.
>
> I'm writing a program which is has a "pool of workers".
>
> So, there is a thread "polling" with poll(2) a set of file descriptors
> to get tasks. When a task is available on some fd, it pass it to a
> worker, who handles the task.
>
> When the worker finishes with the task, it shall return to file
> descriptor to the "poller" thread in order to put it again at the array
> of pollfd data. I do this with a pipe(2) : to awake the poll call, I
> write to one end - the other end is one of the file descriptors on the
> array of pollfd data.

I'm not sure if this is best way. IMHO the better solution is not to pass
control over socket to worker thread (of cource, if if you can do all the
job in the context of polling thread). Then you will not need to introduce
unneeded context switches, you don't need to write to pipe (as you can be
sure that polling thread is not hang in the poll/select at the moment you
operate on the socket).

>
> So, the poll call is waiting on :
> - the read end of the pipe
> - some number of file descriptors (TCP sockets)
>
> The problem is that this works if I use select(2), but not poll(2).
>
> But I'd really want to use pipe, not select. At least, I'd like to
> understand.
>
> And I can't figure out why :
>
> - The worker writes one character on the write end of the pipe;
> - The poll call returns with the correct pipe file descriptor.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
How this

> - the contents of "events" member of the data returned is the same value
> I put before the call (POLLIN | POLLPRI)
> - the contents of "revents" member of the data returned is "0" - no event ???
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
correspond with this?

Do you really check events on the pipe descriptor?


> - if I try to read it, the read call gets blocked.
>
> Thanks for any idea
>
> Jose-Marcio
>
>
>
>

--
Igor Khasilev |
PACO Links, igor at paco dot net |

Jose Marcio Martins da Cruz

8/5/2004 1:44:00 PM

0


Hello,

I bad explained...

igor@notformail.paco.net wrote:
> Jose Marcio Martins da Cruz <martins@paris.ensmp.fr> wrote:

>>
>>When the worker finishes with the task, it shall return to file
>>descriptor to the "poller" thread in order to put it again at the array
>>of pollfd data. I do this with a pipe(2) : to awake the poll call, I
>>write to one end - the other end is one of the file descriptors on the
>>array of pollfd data.
>
>
> I'm not sure if this is best way. IMHO the better solution is not to pass
> control over socket to worker thread (of cource, if if you can do all the
> job in the context of polling thread). Then you will not need to introduce
> unneeded context switches, you don't need to write to pipe (as you can be
> sure that polling thread is not hang in the poll/select at the moment you
> operate on the socket).
>

No, in fact each fd is part of a context. Workers are blocked in a
pthread_cond_wait call. When the controler gets an event on a file
descriptor, it changes the state of the corresponding context and signal
the workers. One of the workers will handle the task.

>
>>So, the poll call is waiting on :

>>
>>- The worker writes one character on the write end of the pipe;
>>- The poll call returns with the correct pipe file descriptor.
>
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> How this
>
>
>>- the contents of "events" member of the data returned is the same value
>>I put before the call (POLLIN | POLLPRI)
>>- the contents of "revents" member of the data returned is "0" - no event ???
>
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> correspond with this?
>
> Do you really check events on the pipe descriptor?
>

Let me give a more explicit example :

I set up a pipe, and the read end of the pipe is one of the fds the poll
is looking at.

When a worker ends his job, it needs to awake the poll call in order to
put the fd he was working on, be included again on the set of file
descriptors the controler is looking at.

So, he writes one character at the write end of the pipe, in order to
awake the controler. The poll call at the controler returns the data
corresponding to the read end of the pipe. Eg.

fd 13 correct
events POLLIN | POLLPRI correct
revents 0 ??????

I don't understand how revents can be 0.... And if I try to read this
file descriptor, the read call gets blocked.

If I use select instead of poll, all this works fine. ...

But I don't want to use select, as at some moment, the value of the file
descriptor can be greater than FD_SETSIZE.



igor

8/5/2004 2:22:00 PM

0

Jose Marcio Martins da Cruz <martins@paris.ensmp.fr> wrote:

>> I'm not sure if this is best way. IMHO the better solution is not to pass
>> control over socket to worker thread (of cource, if if you can do all the
>> job in the context of polling thread). Then you will not need to introduce
>> unneeded context switches, you don't need to write to pipe (as you can be
>> sure that polling thread is not hang in the poll/select at the moment you
>> operate on the socket).
>>
>
> No, in fact each fd is part of a context. Workers are blocked in a

I see. But there is another solution: fd is part of object, not a part of
thread context. When you make fd part of a thread context then you need all
these cond_var signalling, pipe signalling, and other work that you can
easily avoid.

> So, he writes one character at the write end of the pipe, in order to
> awake the controler. The poll call at the controler returns the data
> corresponding to the read end of the pipe. Eg.
>
> fd 13 correct
> events POLLIN | POLLPRI correct
> revents 0 ??????
>
> I don't understand how revents can be 0.... And if I try to read this
> file descriptor, the read call gets blocked.

The only answer I can see: you write to the write end of the pipe, and then
test and read again from the write end of the pipe :)

--
Igor Khasilev |
PACO Links, igor at paco dot net |

Ian Post

8/5/2004 6:53:00 PM

0

Jose Marcio Martins da Cruz <martins@paris.ensmp.fr> wrote:
> So, the poll call is waiting on :
> - the read end of the pipe
> - some number of file descriptors (TCP sockets)

Instead of using a pipe created with pipe(), try using a pair of
sockets created with socketpair(). This work-around might solve your
poll() problem.

Jose Marcio Martins da Cruz

8/5/2004 7:35:00 PM

0

nospam@nowhere.com wrote:
> Jose Marcio Martins da Cruz <martins@paris.ensmp.fr> wrote:
>
>>So, the poll call is waiting on :
>>- the read end of the pipe
>>- some number of file descriptors (TCP sockets)
>
>
> Instead of using a pipe created with pipe(), try using a pair of
> sockets created with socketpair(). This work-around might solve your
> poll() problem.

I've already tried this, and also changing the flags passed in events
member of pollfd struct 8-(