发现代码中有些地方对同一个文件混用了flock(), fcntl()……
例如用b删文时,SR_BMFunc()中有:
flock(arg->fd,LOCK_EX);
if (fromfirst) {
/*走到第一篇*/
conf->new_pos=0; /* atppp 20051019 */
apply_thread(conf,fh,fileheader_thread_read,false,false,(void*)SR_FIRST);
if (conf->new_pos!=0)
conf->pos=conf->new_pos;
}
apply_thread(conf,fh,BM_thread_func,true,true,(void*)&func_arg);
flock(arg->fd,LOCK_UN);
顺着函数调用下去,有可能会调用del_origin(),而del_origin()的实现中:
if (setboardorigin(board, -1)) {
board_regenspecial(board, DIR_MODE_ORIGIN, NULL);
return 0;
}
再顺下去的board_regenspecial()中会尝试对SR_BMFunc()里flock住的.DIR
设置F_RDLCK:
ldata2.l_type = F_RDLCK;
ldata2.l_whence = 0;
ldata2.l_len = 0;
ldata2.l_start = 0;
fcntl(fd2, F_SETLKW, &ldata2);
freebsd的man 2 flock中有:
The flock(), fcntl(2), and lockf(3) locks are compatible. Processes
using different locking interfaces can cooperate over the same file
safely. However, only one of such interfaces should be used within the
same process. If a file is locked by a process through flock(), any
record within the file will be seen as locked from the viewpoint of
another process using fcntl(2) or lockf(3), and vice versa.
就是说freebsd下flock()跟fcntl()的锁是通用的……
而linux下的man 2 flock:
Since kernel 2.0, flock(2) is implemented as a system call in its own
right rather than being emulated in the GNU C library as a call to fcntl(2).
This yields true BSD semantics: there is no interaction between the types
of lock placed by flock(2) and fcntl(2), and flock(2) does not detect deadlock.
linux下flock()跟fcntl()的锁是no interaction的。
所以freebsd下对同一个文件混用fcntl()和flock()就有可能导致死锁,
例如大D删文之后用立即b删文就会激发这个事件。
--
FROM 192.168.14.224