[Gc] I/O issues

Nicolas Cannasse ncannasse at motion-twin.com
Thu Sep 18 05:35:04 PDT 2008


Nicolas Cannasse a écrit :
> Nicolas Cannasse a écrit :
>> Hello,
>>
>> Sorry for the multiple messages recently, we could fix a lot of things 
>> thanks to the help of the people on the list.
>>
>> We are still experiencing one last issue, which is related to I/O 
>> functions.
>>
>> In some rare cases, two of our threads get blocked in a I/O function 
>> (either recv() , fread() , or __read_nocancel()). The two threads are 
>> usually unrelated - one can be a MYSQL response beeing read while the 
>> other is reading a file - but they get blocked at the same time. Seems 
>> like a deadlock to me.
> 
> Ok, we were able to locate the problem :
> 
> It seems that using close() in a finalizer results in breaking the file 
> descriptor table, and might actually close a fd that is still in use 
> somewhere else - sometimes inside a read() - causing havoc in our 
> application.
> 
> Anybody knows where I can find accurate information about close() 
> behavior with pthreads ? It seems it's at least not async-signal-safe.

Reading more about, it indeeds seems like it should be 
async-signal-safe, and that the error is related to what is done here 
but is not exactly the one I guessed first.

Here's a small snip of the code that is use to control another process 
IO asynchronously. It uses both fork()+execvp. A finalizer is registered 
for "p", which will simply close() the 3 file descriptors that are left 
open in the main process. Any problem with GC interaction here ?

---

int input[2], output[2], error[2];
if( pipe(input) || pipe(output) || pipe(error) )
	neko_error();
p->pid = fork();
if( p->pid == -1 )
	neko_error();
// child
if( p->pid == 0 ) {
	close(input[1]);
	close(output[0]);
	close(error[0]);
	dup2(input[0],0);
	dup2(output[1],1);
	dup2(error[1],2);
	execvp(cmd,argv);
	fprintf(stderr,"Command not found : %s\n",val_string(cmd));
	exit(1);
}
// parent
close(input[0]);
close(output[1]);
close(error[1]);
p->iwrite = input[1];
p->oread = output[0];
p->eread = error[0];

-----

Best,
Nicolas


More information about the Gc mailing list