Re: Waiting on more then one event -- Accept_r

Artyom <artyomtnk-/[email protected]>
Newsgroups gmane.comp.web.fastcgi.devel,gmane.spam.detected
Message-ID <[email protected]>
> 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

___________________________________
fastcgi-developers mailing list
http://fastcgi.com/fastcgi-developers/
test.c (text/x-csrc, 823 B)
#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;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.