1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
/* $Cambridge: hermes/src/prayer/lib/mymutex_file.c,v 1.3 2008/09/16 09:59:57 dpc22 Exp $ */
/************************************************
* Prayer - a Webmail Interface *
************************************************/
/* Copyright (c) University of Cambridge 2000 - 2008 */
/* See the file NOTICE for conditions of use and distribution. */
struct mymutex {
struct pool *pool;
char *lockname;
int lockfd;
};
struct mymutex *
mymutex_create(struct pool *pool, char *lockdir, char *name)
{
struct mymutex *mymutex = pool_alloc(pool, sizeof(struct mymutex));
mymutex->pool = pool;
mymutex->lockfd = -1;
if (lockdir && (name[0] != '/'))
mymutex->lockname = pool_strcat3(pool, lockdir, "/", name);
else
mymutex->lockname = pool_strdup(pool, name);
return(mymutex);
}
void
mymutex_free(struct mymutex *mymutex)
{
if (mymutex->lockfd >= 0) close(mymutex->lockfd);
mymutex->lockfd = (-1);
if (!mymutex->pool) {
free(mymutex->lockname);
free(mymutex);
}
}
BOOL
mymutex_slave_init(struct mymutex *mymutex)
{
if ((mymutex->lockfd=open(mymutex->lockname, O_CREAT|O_WRONLY, 0660)) < 0)
log_fatal("Couldn't open lock file: \"%s\": %s",
mymutex->lockname, strerror(errno));
return(T);
}
void
mymutex_slave_cleanup(struct mymutex *mymutex)
{
if (mymutex->lockfd >= 0) close(mymutex->lockfd);
mymutex->lockfd = -1;
}
static BOOL mymutex_alarm_value = NIL;
static void
mymutex_alarm(int arg)
{
mymutex_alarm_value = T;
}
BOOL
mymutex_on(struct mymutex *mymutex, int timeout)
{
int rc;
if (timeout > 0) {
if (!os_signal_alarm_init(mymutex_alarm))
log_fatal("[mymutex_on] Failed to set alarm signal");
alarm(timeout);
}
mymutex_alarm_value = NIL;
do {
rc = os_lock_exclusive_allow_break(mymutex->lockfd);
} while (!mymutex_alarm_value && (rc == NIL) && (errno == EINTR));
if (timeout) {
alarm(0);
os_signal_alarm_clear();
}
if ((rc == NIL) && (errno != EINTR))
log_fatal("[mymutex_on()] failed to release lock: %s",
strerror(errno));
return((mymutex_alarm_value) ? NIL : T);
}
BOOL
mymutex_off(struct mymutex *mymutex)
{
if (!os_lock_release(mymutex->lockfd))
log_fatal("[mymutex_off()] failed to release lock: %s",
strerror(errno));
return(T);
}
|