File: mymutex_file.c

package info (click to toggle)
prayer 1.3.3-dfsg1-3
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 6,388 kB
  • ctags: 3,280
  • sloc: ansic: 42,985; makefile: 805; sh: 451; perl: 166
file content (108 lines) | stat: -rw-r--r-- 2,463 bytes parent folder | download | duplicates (6)
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);
}