source: trunk/lock.c @ 11

Last change on this file since 11 was 11, checked in by moo, 8 years ago

make it build on windows vc compiler

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