Index: trunk/xcache/xc_lock.c
===================================================================
--- trunk/xcache/xc_lock.c	(revision 1198)
+++ trunk/xcache/xc_lock.c	(revision 1199)
@@ -6,4 +6,8 @@
 #ifdef ZEND_WIN32
 #	include <process.h>
+#else
+#	include <unistd.h>
+#	include <fcntl.h>
+#	include <errno.h>
 #endif
 
@@ -23,20 +27,17 @@
 		NULL)
 #endif
-#include "xc_lock.h"
-
-struct _xc_lock_t {
+
+typedef struct {
 	HANDLE fd;
 	char *pathname;
-};
-
+} xc_fcntl_lock_t;
+
+/* {{{ fcntl lock impl */
 #ifndef ZEND_WIN32
-#	include <unistd.h>
-#	include <fcntl.h>
-#	include <errno.h>
 #	define LCK_WR F_WRLCK
 #	define LCK_RD F_RDLCK
 #	define LCK_UN F_UNLCK
 #	define LCK_NB 0
-static inline int dolock(xc_lock_t *lck, int type) /* {{{ */
+static inline int dolock(xc_fcntl_lock_t *lck, int type)
 {
 	int ret;
@@ -54,5 +55,4 @@
 	return ret;
 }
-/* }}} */
 #else
 
@@ -69,5 +69,5 @@
 #	define LCK_UN 0
 #	define LCK_NB LOCKFILE_FAIL_IMMEDIATELY
-static inline int dolock(xc_lock_t *lck, int type) /* {{{ */
+static inline int dolock(xc_fcntl_lock_t *lck, int type)
 {
 	static OVERLAPPED offset = {0, 0, 0, 0, NULL};
@@ -80,11 +80,10 @@
 	}
 }
-/* }}} */
-#endif
-
-xc_lock_t *xc_fcntl_init(const char *pathname) /* {{{ */
+#endif
+/* }}} */
+
+static zend_bool xc_fcntl_init(xc_fcntl_lock_t *lck, const char *pathname) /* {{{ */
 {
 	HANDLE fd;
-	xc_lock_t *lck;
 	int size;
 	char *myname;
@@ -114,5 +113,4 @@
 
 	if (fd != INVALID_HANDLE_VALUE) {
-		lck = malloc(sizeof(lck[0]));
 
 #ifndef __CYGWIN__
@@ -133,8 +131,8 @@
 	}
 
-	return lck;
-}
-/* }}} */
-void xc_fcntl_destroy(xc_lock_t *lck) /* {{{ */
+	return lck ? 1 : 0;
+}
+/* }}} */
+static void xc_fcntl_destroy(xc_fcntl_lock_t *lck) /* {{{ */
 {
 	close(lck->fd);
@@ -143,8 +141,7 @@
 #endif
 	free(lck->pathname);
-	free(lck);
-}
-/* }}} */
-void xc_fcntl_lock(xc_lock_t *lck) /* {{{ */
+}
+/* }}} */
+static void xc_fcntl_lock(xc_fcntl_lock_t *lck) /* {{{ */
 {
 	if (dolock(lck, LCK_WR) < 0) {
@@ -153,5 +150,5 @@
 }
 /* }}} */
-void xc_fcntl_rdlock(xc_lock_t *lck) /* {{{ */
+static void xc_fcntl_rdlock(xc_fcntl_lock_t *lck) /* {{{ */
 {
 	if (dolock(lck, LCK_RD) < 0) {
@@ -160,5 +157,5 @@
 }
 /* }}} */
-void xc_fcntl_unlock(xc_lock_t *lck) /* {{{ */
+static void xc_fcntl_unlock(xc_fcntl_lock_t *lck) /* {{{ */
 {
 	if (dolock(lck, LCK_UN) < 0) {
@@ -167,2 +164,134 @@
 }
 /* }}} */
+
+#undef XC_INTERPROCESS_LOCK_IMPLEMENTED
+#undef XC_LOCK_UNSUED
+
+#ifdef ZEND_WIN32
+#	define XC_INTERPROCESS_LOCK_IMPLEMENTED
+#	ifndef ZTS
+#		define XC_LOCK_UNSUED
+#	endif
+#endif
+
+#if defined(PTHREADS)
+#	define XC_INTERPROCESS_LOCK_IMPLEMENTED
+#endif
+
+struct _xc_lock_t {
+#ifdef XC_LOCK_UNSUED
+	int dummy;
+#else
+#	ifdef ZTS
+	MUTEX_T tsrm_mutex;
+#	endif
+
+#	ifndef XC_INTERPROCESS_LOCK_IMPLEMENTED
+#		ifdef ZTS
+	zend_bool use_fcntl;
+#		endif
+	xc_fcntl_lock_t fcntl_lock;
+#	endif
+#endif
+};
+
+xc_lock_t *xc_lock_init(const char *pathname, int interprocess) /* {{{ */
+{
+#ifdef XC_LOCK_UNSUED
+	return (xc_lock_t *) 1;
+#else
+#	ifdef ZTS
+	xc_lock_t *lck = malloc(sizeof(xc_lock_t));
+#		if defined(PTHREADS)
+	pthread_mutexattr_t psharedm;
+	pthread_mutexattr_init(&psharedm);
+	pthread_mutexattr_setpshared(&psharedm, PTHREAD_PROCESS_SHARED);
+	lck->tsrm_mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
+	pthread_mutex_init(lck->tsrm_mutex, &psharedm);
+#		else
+	lck->tsrm_mutex = tsrm_mutex_alloc();
+#		endif
+#	endif
+#	ifndef XC_INTERPROCESS_LOCK_IMPLEMENTED
+#		ifdef ZTS
+	lck->use_fcntl = interprocess;
+	if (lck->use_fcntl)
+#		endif
+		xc_fcntl_init(&lck->fcntl_lock, pathname);
+#	endif
+	return lck;
+#endif
+}
+/* }}} */
+void xc_lock_destroy(xc_lock_t *lck) /* {{{ */
+{
+#ifdef XC_LOCK_UNSUED
+	/* do nothing */
+#else
+#	ifdef ZTS
+	tsrm_mutex_free(lck->tsrm_mutex);
+#	endif
+#	ifndef XC_INTERPROCESS_LOCK_IMPLEMENTED
+#		ifdef ZTS
+	if (lck->use_fcntl)
+#		endif
+		xc_fcntl_destroy(&lck->fcntl_lock);
+#	endif
+	free(lck);
+#endif
+}
+/* }}} */
+void xc_lock(xc_lock_t *lck) /* {{{ */
+{
+#ifdef XC_LOCK_UNSUED
+#else
+#	ifdef ZTS
+	if (tsrm_mutex_lock(lck->tsrm_mutex) < 0) {
+		zend_error(E_ERROR, "xc_lock failed errno:%d", errno);
+	}
+#	endif
+#	ifndef XC_INTERPROCESS_LOCK_IMPLEMENTED
+#		ifdef ZTS
+	if (lck->use_fcntl)
+#		endif
+		xc_fcntl_lock(&lck->fcntl_lock);
+#	endif
+#endif
+}
+/* }}} */
+void xc_rdlock(xc_lock_t *lck) /* {{{ */
+{
+#ifdef XC_LOCK_UNSUED
+#else
+#	ifdef ZTS
+	if (tsrm_mutex_lock(lck->tsrm_mutex) < 0) {
+		zend_error(E_ERROR, "xc_rdlock failed errno:%d", errno);
+	}
+#	endif
+#	ifndef XC_INTERPROCESS_LOCK_IMPLEMENTED
+#		ifdef ZTS
+	if (lck->use_fcntl)
+#		endif
+		xc_fcntl_lock(&lck->fcntl_lock);
+#	endif
+#endif
+}
+/* }}} */
+void xc_unlock(xc_lock_t *lck) /* {{{ */
+{
+#ifdef XC_LOCK_UNSUED
+#else
+#	ifndef XC_INTERPROCESS_LOCK_IMPLEMENTED
+#		ifdef ZTS
+	if (lck->use_fcntl)
+#		endif
+		xc_fcntl_unlock(&lck->fcntl_lock);
+#	endif
+#endif
+#	ifdef ZTS
+	if (tsrm_mutex_unlock(lck->tsrm_mutex) < 0) {
+		zend_error(E_ERROR, "xc_unlock failed errno:%d", errno);
+	}
+#	endif
+}
+/* }}} */
