By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,938 Members | 2,205 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,938 IT Pros & Developers. It's quick & easy.

Race condition on accept() system call using pthread on Red Hat ES 2.1 (kernel 2.4.9)

P: n/a
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:

Were 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 Im 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_D ETACHED);
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);
}
Nov 14 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
fran <fj*****@yahoo.com.ar> spoke thus:
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


(comp.unix.programmer, comp.programming.threads. It's way OT here,
and pretty OT in comp.lang.c++ as well.)

Your post is off-topic for comp.lang.c. Please visit

http://www.ungerhu.com/jxh/clc.welcome.txt
http://www.eskimo.com/~scs/C-faq/top.html
http://benpfaff.org/writings/clc/off-topic.html

for posting guidelines and frequently asked questions. Thank you.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Nov 14 '05 #2

P: n/a
boa
fran wrote:

As others have mentioned, this is off topic here. Since you seem to be
in big trouble and I know the answer, I will post here with FUT to
comp.programming.threads. Hope that's OK for c.l.c the regulars...

The problem is the way you pass arguments to the new thread. main() and
hijo() shares the same variable, ns, which means that main() can
overwrite the variable before hijo() is able to read it. I guess that
even multiple instances of hijo() can work on the same file descriptor.

The solution? Allocate a pointer an int to the new threads argument(s)
and assign the fd to that int. Then free the allocated memory in hijo().
At least that is one solution. ;-)

HTH
boa@home

[snip]
Nov 14 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.