logo       

Re: Waiting on more then one event -- Accept_r: msg#00003

web.fastcgi.devel

Subject: Re: Waiting on more then one event -- Accept_r

> The locks around select(2) are not necessary, since
> only one
> thread will be woken up by select.

It is not true.

We need locks, I explain:

For example, following this code:

1. select()
2. accept()
3. WorkHard
4. goto 1

Situation:

Thread A executes step 4.
Thread B executes step 3.

Then follow these steps:
A4, A1 (select OK I can continue - exited select)
<interrupt context switch>
B3, B4, B1(select OK), B2, B1 (blocked)
<context switch>
A2 - blocked on accept because data was read by B.

Thus we must have some critical section between
select and accept, otherwise we can't know
if accept will be blocked. select(2) wasn't
designed to do a job for several threads on
same socket. I attached and example of
programs that illustrates such case.

> I'm not sure
> about poll,
> but it will work at least on Linux.
>

poll(2) and select(2) have absolutly same function,
just:
- poll() is not limited on number of descriptors
like select() does.
- poll() has little bit more friendly interface.
and somehow more faster (depends on libraries,
in linux actaully uses select)/
There is difference between epoll and poll. But
epoll/kqueue have actually totally different
semantics.


Artyom
#include <stdio.h>
#include <time.h>
#include <poll.h>
#include <pthread.h>

void *proc1(void *p)
{
char buff[128]={"proc1:"};
struct pollfd fd;
fd.fd=0;
fd.revents=0;
fd.events=POLLIN;
poll(&fd,1,-1);
sleep(10);
char bb[]="I must not block 1\n";
write(1,bb,sizeof(bb)-1);
write(1,buff,read(0,buff+6,128)+6);
write(1,"Exited1\n",8);
return NULL;
}

void *proc2(void *p)
{
char buff[128]={"proc2:"};
struct pollfd fd;
fd.fd=0;
fd.revents=0;
fd.events=POLLIN;
sleep(5);
poll(&fd,1,-1);
char bb[]="I must not block 2\n";
write(1,bb,sizeof(bb)-1);
write(1,buff,read(0,buff+6,128)+6);
write(1,"Exited2\n",8);
return NULL;
}


main()
{
pthread_t pid1,pid2;
pthread_create(&pid1,NULL,proc1,NULL);
pthread_create(&pid2,NULL,proc2,NULL);
pthread_join(pid1,NULL);
pthread_join(pid2,NULL);

return 0;
}

___________________________________
fastcgi-developers mailing list
http://fastcgi.com/fastcgi-developers/
<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise