source: trunk/xcache/xc_lock.c @ 1198

Last change on this file since 1198 was 1198, checked in by moo, 16 months ago

ws fix

  • Property svn:eol-style set to native
File size: 3.3 KB
RevLine 
[1027]1#include "xc_lock.h"
2#include "xcache.h"
[1]3#include <stdio.h>
4#include <string.h>
[36]5#include <stdlib.h>
[1186]6#ifdef ZEND_WIN32
7#   include <process.h>
8#endif
[1]9
10#ifndef ZEND_WIN32
11typedef int HANDLE;
[62]12#   ifndef INVALID_HANDLE_VALUE
13#       define INVALID_HANDLE_VALUE -1
14#   endif
[928]15#else
16#   define close(h) CloseHandle(h)
17#   define open(filename, mode, permission) CreateFile(filename, \
18        GENERIC_READ | GENERIC_WRITE, \
19        FILE_SHARE_READ | FILE_SHARE_WRITE, \
20        NULL, \
21        OPEN_ALWAYS, \
22        FILE_ATTRIBUTE_NORMAL, \
23        NULL)
[1]24#endif
[982]25#include "xc_lock.h"
[1]26
27struct _xc_lock_t {
28    HANDLE fd;
29    char *pathname;
30};
31
32#ifndef ZEND_WIN32
33#   include <unistd.h>
34#   include <fcntl.h>
35#   include <errno.h>
[11]36#   define LCK_WR F_WRLCK
37#   define LCK_RD F_RDLCK
38#   define LCK_UN F_UNLCK
39#   define LCK_NB 0
[1]40static inline int dolock(xc_lock_t *lck, int type) /* {{{ */
[1198]41{
[1]42    int ret;
43    struct flock lock;
44
45    lock.l_type = type;
46    lock.l_start = 0;
47    lock.l_whence = SEEK_SET;
48    lock.l_len = 1;
49    lock.l_pid = 0;
50
51    do {
52        ret = fcntl(lck->fd, F_SETLKW, &lock);
53    } while (ret < 0 && errno == EINTR);
54    return ret;
55}
56/* }}} */
57#else
58
59#   include <win32/flock.h>
60#   include <io.h>
61#   include <fcntl.h>
62#   include <sys/types.h>
63#   include <sys/stat.h>
[928]64#   undef errno
65#   define errno GetLastError()
[11]66#   define getuid() 0
67#   define LCK_WR LOCKFILE_EXCLUSIVE_LOCK
68#   define LCK_RD 0
69#   define LCK_UN 0
70#   define LCK_NB LOCKFILE_FAIL_IMMEDIATELY
[1]71static inline int dolock(xc_lock_t *lck, int type) /* {{{ */
[1198]72{
[1]73    static OVERLAPPED offset = {0, 0, 0, 0, NULL};
74
75    if (type == LCK_UN) {
[11]76        return UnlockFileEx((HANDLE)lck->fd, 0, 1, 0, &offset);
[1]77    }
78    else {
[11]79        return LockFileEx((HANDLE)lck->fd, type, 0, 1, 0, &offset);
[1]80    }
81}
82/* }}} */
83#endif
84
85xc_lock_t *xc_fcntl_init(const char *pathname) /* {{{ */
86{
87    HANDLE fd;
[62]88    xc_lock_t *lck;
89    int size;
90    char *myname;
[1]91
92    if (pathname == NULL) {
[1154]93        static int instanceId = 0;
[62]94        const char default_tmpdir[] = { DEFAULT_SLASH, 't', 'm', 'p', '\0' };
95        const char *tmpdir;
96
97        tmpdir = getenv("TEMP");
98        if (!tmpdir) {
99            tmpdir = getenv("TMP");
100            if (!tmpdir) {
101                tmpdir = default_tmpdir;
102            }
103        }
104        size = strlen(tmpdir) + sizeof("/.xcache.lock") - 1 + 3 * 10 + 100;
[282]105        myname = malloc(size);
[1154]106        snprintf(myname, size - 1, "%s%c.xcache.%d.%d.%d.lock", tmpdir, DEFAULT_SLASH, (int) getuid(), (int) getpid(), ++instanceId);
[1]107        pathname = myname;
108    }
[62]109    else {
110        myname = NULL;
111    }
[1]112
[928]113    fd = open(pathname, O_RDWR|O_CREAT, 0666);
[1]114
[62]115    if (fd != INVALID_HANDLE_VALUE) {
116        lck = malloc(sizeof(lck[0]));
[1]117
118#ifndef __CYGWIN__
119        unlink(pathname);
120#endif
121        lck->fd = fd;
122        size = strlen(pathname) + 1;
123        lck->pathname = malloc(size);
124        memcpy(lck->pathname, pathname, size);
125    }
126    else {
[928]127        zend_error(E_ERROR, "xc_fcntl_create: open(%s, O_RDWR|O_CREAT, 0666) failed:", pathname);
[62]128        lck = NULL;
[1]129    }
[62]130
131    if (myname) {
[282]132        free(myname);
[62]133    }
134
135    return lck;
[1]136}
137/* }}} */
138void xc_fcntl_destroy(xc_lock_t *lck) /* {{{ */
[1198]139{
[928]140    close(lck->fd);
[1]141#ifdef __CYGWIN__
142    unlink(lck->pathname);
143#endif
144    free(lck->pathname);
145    free(lck);
146}
147/* }}} */
148void xc_fcntl_lock(xc_lock_t *lck) /* {{{ */
[1198]149{
[1]150    if (dolock(lck, LCK_WR) < 0) {
[928]151        zend_error(E_ERROR, "xc_fcntl_lock failed errno:%d", errno);
[1]152    }
153}
154/* }}} */
155void xc_fcntl_rdlock(xc_lock_t *lck) /* {{{ */
[1198]156{
[1]157    if (dolock(lck, LCK_RD) < 0) {
[928]158        zend_error(E_ERROR, "xc_fcntl_lock failed errno:%d", errno);
[1]159    }
160}
161/* }}} */
162void xc_fcntl_unlock(xc_lock_t *lck) /* {{{ */
[1198]163{
[1]164    if (dolock(lck, LCK_UN) < 0) {
[928]165        zend_error(E_ERROR, "xc_fcntl_unlock failed errno:%d", errno);
[1]166    }
167}
168/* }}} */
Note: See TracBrowser for help on using the repository browser.