F
fran
Server: IBM XSERIES 225 (Intel Xeon CPU 2.40GHz 1GB RAM)
Operating System: Linux RedHat ES 2.1 kernel 2.4.9
Languaje: C++
Compiler: gcc 2.96
Libs: pthread
We are in need of your help in order to solve the folowing problem:
We´re working on a server side application that implements threads
(pthread under linux Red Hat ES 2.1 kernel 2.4.9). The problem seems
to be a race condition which occurs during an accept() system call, in
which the file descriptor returned is still in use by another thread.
I think there is a confict between the accept() and close() system
calls, and I´m trying to find an alternative solution, changing the
thread based architecture for a fork based architecture.
Attached is a piece of code
Any light you can shed on this difficulty will be greatly appreciated.
Sincerely,
Fran
int main(void){
pthread_t thread_id;
pthread_attr_t attr;
struct protoent *ppe;
struct sockaddr_in sin;
int on=1;
struct linger ling;
int s;
fd_set rd_set,aux_set;
FD_ZERO(&rd_set);
memset(&sin,0,sizeof sin);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(7000);
ppe = getprotobyname("tcp");
if((s = socket(PF_INET,SOCK_STREAM, ppe->o_proto))<0){
exit(1);
}
setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&on,sizeof on);
ling.l_onoff = 1;
ling.l_linger = 10;
setsockopt(s,SOL_SOCKET,SO_LINGER,&ling,sizeof ling);
if(bind(s,(struct sockaddr *)&sin,sizeof sin)<0){
exit(1);
}
if(listen(s,5)<0){
exit(1);
}
FD_SET(s,&rd_set);
while(1){
memcpy(aux_set,rd_set,sizeof(rd_set));
if((ret=select(FD_SETSIZE,&aux_set,NULL,NULL,NULL))>0){
if(FD_ISSET(s,&aux_set)){
if((ns = accept(s,0,0))==(-1)){
exit(1);
}
pthread_attr_init(&attr);
pthread_attr_setdetachstart(&attr,PTHREAD_CREATE_DETACHED);
if(pthread_create(&thread_id,&attr,hijo,(void *)&ns)!=0){
exit(1);
}
}
}
}
}
void hijo(void *arg){
int ns,len;
char trx[1000];
char ans[1000];
ns = *((int*)arg);
memset(trx,0,1000);
memset(ans,0,1000);
// The file descriptor is being corrupted when concurrency level is
high
// At this point . . .
// FD = 7
// LOCALIP = 192.168.102.1
// LOCALPORT = 32333
// REMOTEIP = 192.168.102.10
// REMOTEPORT = 31252
read(ns,trx,1000)
len = generate_answer(trx,ans);
// and then . . .
// FD = 7
// LOCALIP = 40.50.255.255
// LOCALPORT = 0
// REMOTEIP = 30.0.0.0
// REMOTEPORT = 99999
write(s,buff,len);
shutdown(s);
close(s);
}
Operating System: Linux RedHat ES 2.1 kernel 2.4.9
Languaje: C++
Compiler: gcc 2.96
Libs: pthread
We are in need of your help in order to solve the folowing problem:
We´re working on a server side application that implements threads
(pthread under linux Red Hat ES 2.1 kernel 2.4.9). The problem seems
to be a race condition which occurs during an accept() system call, in
which the file descriptor returned is still in use by another thread.
I think there is a confict between the accept() and close() system
calls, and I´m trying to find an alternative solution, changing the
thread based architecture for a fork based architecture.
Attached is a piece of code
Any light you can shed on this difficulty will be greatly appreciated.
Sincerely,
Fran
int main(void){
pthread_t thread_id;
pthread_attr_t attr;
struct protoent *ppe;
struct sockaddr_in sin;
int on=1;
struct linger ling;
int s;
fd_set rd_set,aux_set;
FD_ZERO(&rd_set);
memset(&sin,0,sizeof sin);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(7000);
ppe = getprotobyname("tcp");
if((s = socket(PF_INET,SOCK_STREAM, ppe->o_proto))<0){
exit(1);
}
setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&on,sizeof on);
ling.l_onoff = 1;
ling.l_linger = 10;
setsockopt(s,SOL_SOCKET,SO_LINGER,&ling,sizeof ling);
if(bind(s,(struct sockaddr *)&sin,sizeof sin)<0){
exit(1);
}
if(listen(s,5)<0){
exit(1);
}
FD_SET(s,&rd_set);
while(1){
memcpy(aux_set,rd_set,sizeof(rd_set));
if((ret=select(FD_SETSIZE,&aux_set,NULL,NULL,NULL))>0){
if(FD_ISSET(s,&aux_set)){
if((ns = accept(s,0,0))==(-1)){
exit(1);
}
pthread_attr_init(&attr);
pthread_attr_setdetachstart(&attr,PTHREAD_CREATE_DETACHED);
if(pthread_create(&thread_id,&attr,hijo,(void *)&ns)!=0){
exit(1);
}
}
}
}
}
void hijo(void *arg){
int ns,len;
char trx[1000];
char ans[1000];
ns = *((int*)arg);
memset(trx,0,1000);
memset(ans,0,1000);
// The file descriptor is being corrupted when concurrency level is
high
// At this point . . .
// FD = 7
// LOCALIP = 192.168.102.1
// LOCALPORT = 32333
// REMOTEIP = 192.168.102.10
// REMOTEPORT = 31252
read(ns,trx,1000)
len = generate_answer(trx,ans);
// and then . . .
// FD = 7
// LOCALIP = 40.50.255.255
// LOCALPORT = 0
// REMOTEIP = 30.0.0.0
// REMOTEPORT = 99999
write(s,buff,len);
shutdown(s);
close(s);
}