source: trunk/lock.c @ 1

Last change on this file since 1 was 1, checked in by moo, 9 years ago

initial import to online

File size: 2.5 KB
RevLine 
[1]1#include <stdio.h>
2#include <string.h>
3#include <malloc.h>
4
5#include <php.h>
6#ifndef ZEND_WIN32
7typedef int HANDLE;
8#endif
9#include "lock.h"
10
11struct _xc_lock_t {
12    HANDLE fd;
13    char *pathname;
14};
15
16#ifndef ZEND_WIN32
17#   include <unistd.h>
18#   include <fcntl.h>
19#   include <errno.h>
20static inline int dolock(xc_lock_t *lck, int type) /* {{{ */
21{ 
22    int ret;
23    struct flock lock;
24
25    lock.l_type = type;
26    lock.l_start = 0;
27    lock.l_whence = SEEK_SET;
28    lock.l_len = 1;
29    lock.l_pid = 0;
30
31    do {
32        ret = fcntl(lck->fd, F_SETLKW, &lock);
33    } while (ret < 0 && errno == EINTR);
34    return ret;
35}
36/* }}} */
37#define LCK_WR F_WRLCK
38#define LCK_RD F_RDLCK
39#define LCK_UN F_UNLCK
40#define LCK_NB 0
41#else
42
43#   include <win32/flock.h>
44#   include <io.h>
45#   include <fcntl.h>
46#   include <sys/types.h>
47#   include <sys/stat.h>
48#   define errno GetLastError()
49static inline int dolock(xc_lock_t *lck, int type) /* {{{ */
50{ 
51    static OVERLAPPED offset = {0, 0, 0, 0, NULL};
52
53    if (type == LCK_UN) {
54        return UnlockFileEx((HANDLE)fd, 0, 1, 0, &offset);
55    }
56    else {
57        return LockFileEx((HANDLE)fd, type, 0, 1, 0, &offset);
58    }
59}
60/* }}} */
61#define LCK_WR LOCKFILE_EXCLUSIVE_LOCK
62#define LCK_RD 0
63#define LCK_UN 0
64#define LCK_NB LOCKFILE_FAIL_IMMEDIATELY
65#endif
66
67xc_lock_t *xc_fcntl_init(const char *pathname) /* {{{ */
68{
69    HANDLE fd;
70    char myname[sizeof("/tmp/.xcache.lock") - 1 + 20];
71
72    if (pathname == NULL) {
73        static int i = 0;
74        snprintf(myname, sizeof(myname) - 1, "/tmp/.xcache.%d.%d.lock", (int) getuid(), i ++);
75        pathname = myname;
76    }
77
78    fd = open(pathname, O_RDWR|O_CREAT, 0666);
79
80    if (fd > 0) {
81        xc_lock_t *lck = malloc(sizeof(lck[0]));
82        int size;
83
84#ifndef __CYGWIN__
85        unlink(pathname);
86#endif
87        lck->fd = fd;
88        size = strlen(pathname) + 1;
89        lck->pathname = malloc(size);
90        memcpy(lck->pathname, pathname, size);
91        return lck;
92    }
93    else {
94        fprintf(stderr, "xc_fcntl_create: open(%s, O_RDWR|O_CREAT, 0666) failed:", pathname);
95        return NULL;
96    }
97}
98/* }}} */
99void xc_fcntl_destroy(xc_lock_t *lck) /* {{{ */
100{   
101    close(lck->fd);
102#ifdef __CYGWIN__
103    unlink(lck->pathname);
104#endif
105    free(lck->pathname);
106    free(lck);
107}
108/* }}} */
109void xc_fcntl_lock(xc_lock_t *lck) /* {{{ */
110{   
111    if (dolock(lck, LCK_WR) < 0) {
112        fprintf(stderr, "xc_fcntl_lock failed errno:%d", errno);
113    }
114}
115/* }}} */
116void xc_fcntl_rdlock(xc_lock_t *lck) /* {{{ */
117{   
118    if (dolock(lck, LCK_RD) < 0) {
119        fprintf(stderr, "xc_fcntl_lock failed errno:%d", errno);
120    }
121}
122/* }}} */
123void xc_fcntl_unlock(xc_lock_t *lck) /* {{{ */
124{   
125    if (dolock(lck, LCK_UN) < 0) {
126        fprintf(stderr, "xc_fcntl_unlock failed errno:%d", errno);
127    }
128}
129/* }}} */
Note: See TracBrowser for help on using the repository browser.