Sleep forever waiting for lock. Previous method doesn't work well with
a large number of clients accessing the cache at the same time, and there is no simple way to add a timeout to the lock. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@13019 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -58,9 +58,6 @@ struct fcc_cursor {
|
|||||||
|
|
||||||
#define FCC_CURSOR(C) ((struct fcc_cursor*)(C))
|
#define FCC_CURSOR(C) ((struct fcc_cursor*)(C))
|
||||||
|
|
||||||
#define KRB5_CC_LOCK_RETRY_COUNT 50
|
|
||||||
#define KRB5_CC_LOCK_RETRY 1
|
|
||||||
|
|
||||||
static const char*
|
static const char*
|
||||||
fcc_get_name(krb5_context context,
|
fcc_get_name(krb5_context context,
|
||||||
krb5_ccache id)
|
krb5_ccache id)
|
||||||
@@ -71,16 +68,23 @@ fcc_get_name(krb5_context context,
|
|||||||
static int
|
static int
|
||||||
xlock(int fd, krb5_boolean exclusive)
|
xlock(int fd, krb5_boolean exclusive)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
#ifdef HAVE_FCNTL
|
#ifdef HAVE_FCNTL
|
||||||
struct flock l;
|
struct flock l;
|
||||||
|
|
||||||
l.l_start = 0;
|
l.l_start = 0;
|
||||||
l.l_len = 0;
|
l.l_len = 0;
|
||||||
l.l_type = exclusive ? F_WRLCK : F_RDLCK;
|
l.l_type = exclusive ? F_WRLCK : F_RDLCK;
|
||||||
l.l_whence = SEEK_SET;
|
l.l_whence = SEEK_SET;
|
||||||
return fcntl(fd, F_SETLK, &l);
|
ret = fcntl(fd, F_SETLKW, &l);
|
||||||
#else
|
#else
|
||||||
return flock(fd, (exclusive ? LOCK_EX : LOCK_SH) | LOCK_NB);
|
ret = flock(fd, exclusive ? LOCK_EX : LOCK_SH);
|
||||||
#endif
|
#endif
|
||||||
|
if(ret < 0)
|
||||||
|
ret = errno;
|
||||||
|
if(ret == EACCES) /* fcntl can return EACCES instead of EAGAIN */
|
||||||
|
ret = EAGAIN;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -92,7 +96,7 @@ xunlock(int fd)
|
|||||||
l.l_len = 0;
|
l.l_len = 0;
|
||||||
l.l_type = F_UNLCK;
|
l.l_type = F_UNLCK;
|
||||||
l.l_whence = SEEK_SET;
|
l.l_whence = SEEK_SET;
|
||||||
return fcntl(fd, F_SETLK, &l);
|
return fcntl(fd, F_SETLKW, &l);
|
||||||
#else
|
#else
|
||||||
return flock(fd, LOCK_UN);
|
return flock(fd, LOCK_UN);
|
||||||
#endif
|
#endif
|
||||||
@@ -103,18 +107,8 @@ fcc_lock(krb5_context context, krb5_ccache id,
|
|||||||
int fd, krb5_boolean exclusive)
|
int fd, krb5_boolean exclusive)
|
||||||
{
|
{
|
||||||
krb5_error_code ret = 0;
|
krb5_error_code ret = 0;
|
||||||
int i;
|
ret = xlock(fd, exclusive);
|
||||||
for (i = 0; i < KRB5_CC_LOCK_RETRY_COUNT; i++) {
|
if(ret == EAGAIN)
|
||||||
if (xlock(fd, exclusive) < 0) {
|
|
||||||
ret = errno;
|
|
||||||
if(ret == EAGAIN) {
|
|
||||||
sleep(KRB5_CC_LOCK_RETRY);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(ret == EAGAIN)
|
|
||||||
krb5_set_error_string(context, "timed out locking cache file %s",
|
krb5_set_error_string(context, "timed out locking cache file %s",
|
||||||
fcc_get_name(context, id));
|
fcc_get_name(context, id));
|
||||||
else if(ret != 0)
|
else if(ret != 0)
|
||||||
|
Reference in New Issue
Block a user