summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/ipc/ipcd/extensions/lock
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/xpcom18a4/ipc/ipcd/extensions/lock')
-rw-r--r--src/libs/xpcom18a4/ipc/ipcd/extensions/lock/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/ipc/ipcd/extensions/lock/Makefile.in52
-rw-r--r--src/libs/xpcom18a4/ipc/ipcd/extensions/lock/public/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/ipc/ipcd/extensions/lock/public/Makefile.in58
-rw-r--r--src/libs/xpcom18a4/ipc/ipcd/extensions/lock/public/ipcILockService.idl65
-rw-r--r--src/libs/xpcom18a4/ipc/ipcd/extensions/lock/public/ipcLockCID.h53
-rw-r--r--src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/Makefile.in69
-rw-r--r--src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/ipcLockProtocol.cpp87
-rw-r--r--src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/ipcLockProtocol.h98
-rw-r--r--src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/ipcLockService.cpp168
-rw-r--r--src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/ipcLockService.h63
-rw-r--r--src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/module/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/module/Makefile.in92
-rw-r--r--src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/module/ipcLockModule.cpp337
-rw-r--r--src/libs/xpcom18a4/ipc/ipcd/extensions/lock/test/Makefile.in67
-rw-r--r--src/libs/xpcom18a4/ipc/ipcd/extensions/lock/test/TestIPCLocks.cpp244
17 files changed, 1457 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/.cvsignore b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/Makefile.in b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/Makefile.in
new file mode 100644
index 00000000..4b94a31f
--- /dev/null
+++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/Makefile.in
@@ -0,0 +1,52 @@
+# vim: noexpandtab ts=4 sw=4
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla IPC.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2002
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Darin Fisher <darin@netscape.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+DIRS = public src
+
+ifdef ENABLE_TESTS
+DIRS += test
+endif
+
+include $(topsrcdir)/config/rules.mk
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/public/.cvsignore b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/public/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/public/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/public/Makefile.in b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/public/Makefile.in
new file mode 100644
index 00000000..9a08abdb
--- /dev/null
+++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/public/Makefile.in
@@ -0,0 +1,58 @@
+# vim: noexpandtab ts=4 sw=4
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla IPC.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2002
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Darin Fisher <darin@netscape.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../../../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = ipcd
+XPIDL_MODULE = ipcd_lock
+
+EXPORTS = \
+ ipcLockCID.h \
+ $(NULL)
+
+XPIDLSRCS = \
+ ipcILockService.idl \
+ $(NULL)
+
+include $(topsrcdir)/config/rules.mk
+
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/public/ipcILockService.idl b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/public/ipcILockService.idl
new file mode 100644
index 00000000..1cbf8651
--- /dev/null
+++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/public/ipcILockService.idl
@@ -0,0 +1,65 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPC.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsISupports.idl"
+
+/**
+ * This service provides named interprocess locking.
+ */
+[scriptable, uuid(9f6dbe15-d851-4b00-912a-5ac0be88a409)]
+interface ipcILockService : nsISupports
+{
+ /**
+ * Call this method to acquire a named interprocess lock.
+ *
+ * @param aLockName
+ * specifies the name of the lock
+ * @param aWaitIfBusy
+ * wait for the lock to become available; otherwise, fail if lock
+ * is already held by some other process.
+ */
+ void acquireLock(in string aLockName,
+ in boolean aWaitIfBusy);
+
+ /**
+ * Call this method to release a named lock.
+ *
+ * @param aLockName
+ * specifies the name of the lock
+ */
+ void releaseLock(in string aLockName);
+};
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/public/ipcLockCID.h b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/public/ipcLockCID.h
new file mode 100644
index 00000000..ba756d9b
--- /dev/null
+++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/public/ipcLockCID.h
@@ -0,0 +1,53 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPC.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef ipcLockCID_h__
+#define ipcLockCID_h__
+
+#define IPC_LOCKSERVICE_CLASSNAME \
+ "ipcLockService"
+#define IPC_LOCKSERVICE_CONTRACTID \
+ "@mozilla.org/ipc/lock-service;1"
+#define IPC_LOCKSERVICE_CID \
+{ /* d9e56bf8-e32e-4b6d-87f1-06d73b0ce7ca */ \
+ 0xd9e56bf8, \
+ 0xe32e, \
+ 0x4b6d, \
+ {0x87, 0xf1, 0x06, 0xd7, 0x3b, 0x0c, 0xe7, 0xca} \
+}
+
+#endif // !ipcLockCID_h__
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/.cvsignore b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/Makefile.in b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/Makefile.in
new file mode 100644
index 00000000..26d943a8
--- /dev/null
+++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/Makefile.in
@@ -0,0 +1,69 @@
+# vim: noexpandtab ts=4 sw=4
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla IPC.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2002
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Darin Fisher <darin@netscape.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../../../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+DIRS = module
+
+MODULE = ipcd
+LIBRARY_NAME = ipcdlock_s
+FORCE_STATIC_LIB = 1
+MODULE_NAME = ipcd
+
+FORCE_USE_PIC = 1
+
+REQUIRES = \
+ xpcom \
+ string \
+ $(NULL)
+
+CPPSRCS = \
+ ipcLockProtocol.cpp \
+ ipcLockService.cpp \
+ $(NULL)
+
+LOCAL_INCLUDES = \
+ -I$(srcdir)/../../../shared/src \
+ $(NULL)
+
+include $(topsrcdir)/config/rules.mk
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/ipcLockProtocol.cpp b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/ipcLockProtocol.cpp
new file mode 100644
index 00000000..5a7e7755
--- /dev/null
+++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/ipcLockProtocol.cpp
@@ -0,0 +1,87 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPC.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdlib.h>
+#include <string.h>
+#include "prlog.h"
+#include "ipcLockProtocol.h"
+
+//-----------------------------------------------------------------------------
+
+static inline PRUint8 get_opcode(const PRUint8 *buf)
+{
+ return (buf[0] & 0x0f);
+}
+
+static inline PRUint8 get_flags(const PRUint8 *buf)
+{
+ return (buf[0] & 0xf0) >> 4;
+}
+
+static inline const char *get_key(const PRUint8 *buf)
+{
+ return ((const char *) buf) + 1;
+}
+
+//-----------------------------------------------------------------------------
+
+PRUint8 *
+IPC_FlattenLockMsg(const ipcLockMsg *msg, PRUint32 *bufLen)
+{
+ PRUint32 len = 1 // header byte
+ + strlen(msg->key) // key
+ + 1; // null terminator
+
+ PRUint8 *buf = (PRUint8 *) ::operator new(len);
+ if (!buf)
+ return NULL;
+
+ buf[0] = (msg->opcode | (msg->flags << 4));
+
+ memcpy(&buf[1], msg->key, len - 1);
+ *bufLen = len;
+ return buf;
+}
+
+void
+IPC_UnflattenLockMsg(const PRUint8 *buf, PRUint32 bufLen, ipcLockMsg *msg)
+{
+ PR_ASSERT(bufLen > 2); // malformed buffer otherwise
+ msg->opcode = get_opcode(buf);
+ msg->flags = get_flags(buf);
+ msg->key = get_key(buf);
+}
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/ipcLockProtocol.h b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/ipcLockProtocol.h
new file mode 100644
index 00000000..b74b5cde
--- /dev/null
+++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/ipcLockProtocol.h
@@ -0,0 +1,98 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPC.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef ipcLockProtocol_h__
+#define ipcLockProtocol_h__
+
+#include "prtypes.h"
+
+//
+// ipc lock message format:
+//
+// +----------------------------------+
+// | opcode : 4 bits |
+// +----------------------------------+
+// | flags : 4 bits |
+// +----------------------------------+
+// | key : null terminated string |
+// +----------------------------------+
+//
+
+// lock opcodes
+#define IPC_LOCK_OP_ACQUIRE 1
+#define IPC_LOCK_OP_RELEASE 2
+#define IPC_LOCK_OP_STATUS_ACQUIRED 3
+#define IPC_LOCK_OP_STATUS_FAILED 4
+#define IPC_LOCK_OP_STATUS_BUSY 5
+
+// lock flags
+#define IPC_LOCK_FL_NONBLOCKING 1
+
+// data structure for representing lock request message
+struct ipcLockMsg
+{
+ PRUint8 opcode;
+ PRUint8 flags;
+ const char * key;
+};
+
+//
+// flatten a lock message
+//
+// returns a malloc'd buffer containing the flattened message. on return,
+// bufLen contains the length of the flattened message.
+//
+PRUint8 *IPC_FlattenLockMsg(const ipcLockMsg *msg, PRUint32 *bufLen);
+
+//
+// unflatten a lock message. upon return, msg->key points into buf, so
+// buf must not be deallocated until after msg is no longer needed.
+//
+void IPC_UnflattenLockMsg(const PRUint8 *buf, PRUint32 bufLen, ipcLockMsg *msg);
+
+//
+// TargetID for message passing
+//
+#define IPC_LOCK_TARGETID \
+{ /* 703ada8a-2d38-4d5d-9d39-03d1ccceb567 */ \
+ 0x703ada8a, \
+ 0x2d38, \
+ 0x4d5d, \
+ {0x9d, 0x39, 0x03, 0xd1, 0xcc, 0xce, 0xb5, 0x67} \
+}
+
+#endif // !ipcLockProtocol_h__
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/ipcLockService.cpp b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/ipcLockService.cpp
new file mode 100644
index 00000000..771aa787
--- /dev/null
+++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/ipcLockService.cpp
@@ -0,0 +1,168 @@
+/* vim:set ts=4 sw=4 sts=4 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPC.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdlib.h>
+#include "nsDependentString.h"
+#include "nsHashKeys.h"
+#include "nsAutoPtr.h"
+#include "ipcLockService.h"
+#include "ipcLockProtocol.h"
+#include "ipcLog.h"
+#include "prthread.h"
+
+static const nsID kLockTargetID = IPC_LOCK_TARGETID;
+
+//-----------------------------------------------------------------------------
+
+struct ipcPendingLock
+{
+ const char *name;
+ nsresult status;
+ PRBool complete;
+};
+
+//-----------------------------------------------------------------------------
+
+nsresult
+ipcLockService::Init()
+{
+ if (PR_NewThreadPrivateIndex(&mTPIndex, nsnull) != PR_SUCCESS)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ // Configure OnMessageAvailable to be called on the IPC thread. This is
+ // done to allow us to proxy OnAcquireLockComplete events to the right
+ // thread immediately even if the main thread is blocked waiting to acquire
+ // some other lock synchronously.
+
+ return IPC_DefineTarget(kLockTargetID, this, PR_FALSE);
+}
+
+NS_IMPL_THREADSAFE_ISUPPORTS2(ipcLockService, ipcILockService, ipcIMessageObserver)
+
+NS_IMETHODIMP
+ipcLockService::AcquireLock(const char *lockName, PRBool waitIfBusy)
+{
+ LOG(("ipcLockService::AcquireLock [lock=%s wait=%u]\n", lockName, waitIfBusy));
+
+ ipcLockMsg msg;
+ msg.opcode = IPC_LOCK_OP_ACQUIRE;
+ msg.flags = (waitIfBusy ? 0 : IPC_LOCK_FL_NONBLOCKING);
+ msg.key = lockName;
+
+ PRUint32 bufLen;
+ nsAutoPtr<PRUint8> buf( IPC_FlattenLockMsg(&msg, &bufLen) );
+ if (!buf)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ ipcPendingLock pendingLock;
+ pendingLock.name = lockName;
+ pendingLock.status = 0xDEADBEEF; // something bogus
+ pendingLock.complete = PR_FALSE;
+ if (PR_SetThreadPrivate(mTPIndex, &pendingLock) != PR_SUCCESS)
+ return NS_ERROR_UNEXPECTED;
+
+ // prevent our OnMessageAvailable from being called until we explicitly ask
+ // for it to be called via IPC_WaitMessage.
+ IPC_DISABLE_MESSAGE_OBSERVER_FOR_SCOPE(kLockTargetID);
+
+ nsresult rv = IPC_SendMessage(0, kLockTargetID, buf, bufLen);
+ if (NS_SUCCEEDED(rv)) {
+ do {
+ // block the calling thread until we get a response from the daemon
+ rv = IPC_WaitMessage(0, kLockTargetID, this, nsnull, PR_INTERVAL_NO_TIMEOUT);
+ }
+ while (NS_SUCCEEDED(rv) && !pendingLock.complete);
+
+ if (NS_SUCCEEDED(rv))
+ rv = pendingLock.status;
+ }
+
+ // we could clear the TPD, but that isn't really necessary.
+
+ return rv;
+}
+
+NS_IMETHODIMP
+ipcLockService::ReleaseLock(const char *lockName)
+{
+ LOG(("ipcLockService::ReleaseLock [lock=%s]\n", lockName));
+
+ ipcLockMsg msg;
+ msg.opcode = IPC_LOCK_OP_RELEASE;
+ msg.flags = 0;
+ msg.key = lockName;
+
+ PRUint32 bufLen;
+ PRUint8 *buf = IPC_FlattenLockMsg(&msg, &bufLen);
+ if (!buf)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ nsresult rv = IPC_SendMessage(0, kLockTargetID, buf, bufLen);
+ delete buf;
+
+ if (NS_FAILED(rv))
+ return rv;
+
+ return NS_OK;
+}
+
+// called on the same thread that called IPC_WaitMessage
+NS_IMETHODIMP
+ipcLockService::OnMessageAvailable(PRUint32 unused, const nsID &target,
+ const PRUint8 *data, PRUint32 dataLen)
+{
+ ipcLockMsg msg;
+ IPC_UnflattenLockMsg(data, dataLen, &msg);
+
+ LOG(("ipcLockService::OnMessageAvailable [lock=%s opcode=%u]\n", msg.key, msg.opcode));
+
+ ipcPendingLock *pendingLock = (ipcPendingLock *) PR_GetThreadPrivate(mTPIndex);
+ if (strcmp(pendingLock->name, msg.key) == 0) {
+ pendingLock->complete = PR_TRUE;
+ if (msg.opcode == IPC_LOCK_OP_STATUS_ACQUIRED)
+ pendingLock->status = NS_OK;
+ else
+ pendingLock->status = NS_ERROR_FAILURE;
+ return NS_OK;
+ }
+
+ LOG(("message does not match; waiting for another...\n"));
+
+ // else, we got a message that another thread is waiting to receive.
+ return IPC_WAIT_NEXT_MESSAGE;
+}
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/ipcLockService.h b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/ipcLockService.h
new file mode 100644
index 00000000..6014172b
--- /dev/null
+++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/ipcLockService.h
@@ -0,0 +1,63 @@
+/* vim:set ts=4 sw=4 sts=4 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPC.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef ipcLockService_h__
+#define ipcLockService_h__
+
+#include "ipcILockService.h"
+#include "ipcdclient.h"
+
+//-----------------------------------------------------------------------------
+
+class ipcLockService : public ipcILockService
+ , public ipcIMessageObserver
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_IPCILOCKSERVICE
+ NS_DECL_IPCIMESSAGEOBSERVER
+
+ NS_HIDDEN_(nsresult) Init();
+
+private:
+ PRUintn mTPIndex;
+};
+
+//-----------------------------------------------------------------------------
+
+#endif // !ipcLockService_h__
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/module/.cvsignore b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/module/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/module/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/module/Makefile.in b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/module/Makefile.in
new file mode 100644
index 00000000..b35db1bc
--- /dev/null
+++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/module/Makefile.in
@@ -0,0 +1,92 @@
+# vim: noexpandtab ts=4 sw=4
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla IPC.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2002
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Darin Fisher <darin@netscape.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../../../../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = ipcd
+LIBRARY_NAME = lockmodule
+ifeq ($(OS_ARCH), OS2)
+SHORT_LIBNAME = lockmod
+endif
+MODULE_NAME = ipcd
+
+FORCE_SHARED_LIB = 1
+NO_DIST_INSTALL = 1
+NO_INSTALL = 1
+
+ifeq ($(OS_ARCH),Darwin)
+NO_COMPONENT_LINK_MAP = 1
+MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS =
+endif
+
+# required for #include "nsID.h"
+REQUIRES = \
+ xpcom \
+ $(NULL)
+
+CPPSRCS = ipcLockModule.cpp
+
+LOCAL_INCLUDES = \
+ -I$(srcdir)/.. \
+ $(NULL)
+
+EXTRA_OBJS = ../ipcLockProtocol.$(OBJ_SUFFIX)
+
+EXTRA_DSO_LDOPTS = \
+ $(LIBS_DIR) \
+ $(NSPR_LIBS) \
+ $(EXTRA_DSO_LIBS) \
+ $(EXTRA_OBJS) \
+ $(NULL)
+
+include $(topsrcdir)/config/rules.mk
+
+_IPC_FILES = \
+ $(DLL_PREFIX)$(LIBRARY_NAME)$(DLL_SUFFIX) \
+ $(NULL)
+
+libs:: $(_IPC_FILES)
+ $(INSTALL) $^ $(DIST)/bin/ipc/modules
+
+install:: $(_IPC_FILES)
+ $(SYSINSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir)/ipc/modules
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/module/ipcLockModule.cpp b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/module/ipcLockModule.cpp
new file mode 100644
index 00000000..151c0f89
--- /dev/null
+++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/src/module/ipcLockModule.cpp
@@ -0,0 +1,337 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPC.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "ipcModuleUtil.h"
+#include "ipcLockProtocol.h"
+#include "plhash.h"
+#include "plstr.h"
+
+#ifdef DEBUG
+#define LOG(args) printf args
+#else
+#define LOG(args)
+#endif
+
+static const nsID kLockTargetID = IPC_LOCK_TARGETID;
+
+static void
+ipcLockModule_Send(PRUint32 cid, const char *key, PRUint8 opcode)
+{
+ ipcLockMsg msg = { opcode, 0, key };
+ PRUint32 bufLen;
+ PRUint8 *buf = IPC_FlattenLockMsg(&msg, &bufLen);
+ if (!buf)
+ return;
+ IPC_SendMsg(cid, kLockTargetID, buf, bufLen);
+ free(buf);
+}
+
+//-----------------------------------------------------------------------------
+
+//
+// gLockTable stores mapping from lock name to ipcLockContext
+//
+static PLHashTable *gLockTable = NULL;
+
+//-----------------------------------------------------------------------------
+
+struct ipcLockContext
+{
+ PRUint32 mOwnerID; // client ID of this lock's owner
+ struct ipcLockContext *mNextPending; // pointer to client next in line to
+ // acquire this lock.
+
+ ipcLockContext(PRUint32 ownerID)
+ : mOwnerID(ownerID)
+ , mNextPending(NULL) {}
+};
+
+//-----------------------------------------------------------------------------
+
+PR_STATIC_CALLBACK(void *)
+ipcLockModule_AllocTable(void *pool, PRSize size)
+{
+ return malloc(size);
+}
+
+PR_STATIC_CALLBACK(void)
+ipcLockModule_FreeTable(void *pool, void *item)
+{
+ free(item);
+}
+
+PR_STATIC_CALLBACK(PLHashEntry *)
+ipcLockModule_AllocEntry(void *pool, const void *key)
+{
+ return (PLHashEntry *) malloc(sizeof(PLHashEntry));
+}
+
+PR_STATIC_CALLBACK(void)
+ipcLockModule_FreeEntry(void *pool, PLHashEntry *he, PRUintn flag)
+{
+ PL_strfree((char *) he->key);
+ free(he);
+}
+
+static const PLHashAllocOps ipcLockModule_AllocOps = {
+ ipcLockModule_AllocTable,
+ ipcLockModule_FreeTable,
+ ipcLockModule_AllocEntry,
+ ipcLockModule_FreeEntry
+};
+
+//-----------------------------------------------------------------------------
+
+static void
+ipcLockModule_AcquireLock(PRUint32 cid, PRUint8 flags, const char *key)
+{
+ LOG(("$$$ acquiring lock [key=%s]\n", key));
+
+ if (!gLockTable)
+ return;
+
+ ipcLockContext *ctx;
+
+ ctx = (ipcLockContext *) PL_HashTableLookup(gLockTable, key);
+ if (ctx) {
+ //
+ // lock is already acquired, add this client to the queue. make
+ // sure this client doesn't already own the lock or live on the queue.
+ //
+ while (ctx->mOwnerID != cid && ctx->mNextPending)
+ ctx = ctx->mNextPending;
+ if (ctx->mOwnerID != cid) {
+ //
+ // if nonblocking, then send busy status message. otherwise,
+ // proceed to add this client to the pending queue.
+ //
+ if (flags & IPC_LOCK_FL_NONBLOCKING)
+ ipcLockModule_Send(cid, key, IPC_LOCK_OP_STATUS_BUSY);
+ else
+ ctx->mNextPending = new ipcLockContext(cid);
+ }
+ }
+ else {
+ //
+ // ok, add this lock to the table, and notify client that it now owns
+ // the lock!
+ //
+ ctx = new ipcLockContext(cid);
+ if (!ctx)
+ return;
+
+ PL_HashTableAdd(gLockTable, PL_strdup(key), ctx);
+
+ ipcLockModule_Send(cid, key, IPC_LOCK_OP_STATUS_ACQUIRED);
+ }
+}
+
+static PRBool
+ipcLockModule_ReleaseLockHelper(PRUint32 cid, const char *key, ipcLockContext *ctx)
+{
+ LOG(("$$$ releasing lock [key=%s]\n", key));
+
+ PRBool removeEntry = PR_FALSE;
+
+ //
+ // lock is already acquired _or_ maybe client is on the pending list.
+ //
+ if (ctx->mOwnerID == cid) {
+ if (ctx->mNextPending) {
+ //
+ // remove this element from the list. since this is the
+ // first element in the list, instead of removing it we
+ // shift the data from the next context into this one and
+ // delete the next context.
+ //
+ ipcLockContext *next = ctx->mNextPending;
+ ctx->mOwnerID = next->mOwnerID;
+ ctx->mNextPending = next->mNextPending;
+ delete next;
+ //
+ // notify client that it now owns the lock
+ //
+ ipcLockModule_Send(ctx->mOwnerID, key, IPC_LOCK_OP_STATUS_ACQUIRED);
+ }
+ else {
+ delete ctx;
+ removeEntry = PR_TRUE;
+ }
+ }
+ else {
+ ipcLockContext *prev;
+ for (;;) {
+ prev = ctx;
+ ctx = ctx->mNextPending;
+ if (!ctx)
+ break;
+ if (ctx->mOwnerID == cid) {
+ // remove ctx from list
+ prev->mNextPending = ctx->mNextPending;
+ delete ctx;
+ break;
+ }
+ }
+ }
+
+ return removeEntry;
+}
+
+static void
+ipcLockModule_ReleaseLock(PRUint32 cid, const char *key)
+{
+ if (!gLockTable)
+ return;
+
+ ipcLockContext *ctx;
+
+ ctx = (ipcLockContext *) PL_HashTableLookup(gLockTable, key);
+ if (ctx && ipcLockModule_ReleaseLockHelper(cid, key, ctx))
+ PL_HashTableRemove(gLockTable, key);
+}
+
+PR_STATIC_CALLBACK(PRIntn)
+ipcLockModule_ReleaseByCID(PLHashEntry *he, PRIntn i, void *arg)
+{
+ PRUint32 cid = *(PRUint32 *) arg;
+
+ ipcLockContext *ctx = (ipcLockContext *) he->value;
+ if (ctx->mOwnerID != cid)
+ return HT_ENUMERATE_NEXT;
+
+ LOG(("$$$ ipcLockModule_ReleaseByCID [cid=%u key=%s he=%p]\n",
+ cid, (char*)he->key, (void*)he));
+
+ if (ipcLockModule_ReleaseLockHelper(cid, (const char *) he->key, ctx))
+ return HT_ENUMERATE_REMOVE;
+
+ return HT_ENUMERATE_NEXT;
+}
+
+//-----------------------------------------------------------------------------
+
+static void
+ipcLockModule_Init()
+{
+ LOG(("$$$ ipcLockModule_Init\n"));
+
+ gLockTable = PL_NewHashTable(32,
+ PL_HashString,
+ PL_CompareStrings,
+ PL_CompareValues,
+ &ipcLockModule_AllocOps,
+ NULL);
+}
+
+static void
+ipcLockModule_Shutdown()
+{
+ LOG(("$$$ ipcLockModule_Shutdown\n"));
+
+ if (gLockTable) {
+ // XXX walk table destroying all ipcLockContext objects
+
+ PL_HashTableDestroy(gLockTable);
+ gLockTable = NULL;
+ }
+}
+
+static void
+ipcLockModule_HandleMsg(ipcClientHandle client,
+ const nsID &target,
+ const void *data,
+ PRUint32 dataLen)
+{
+ PRUint32 cid = IPC_GetClientID(client);
+
+ LOG(("$$$ ipcLockModule_HandleMsg [cid=%u]\n", cid));
+
+ ipcLockMsg msg;
+ IPC_UnflattenLockMsg((const PRUint8 *) data, dataLen, &msg);
+
+ switch (msg.opcode) {
+ case IPC_LOCK_OP_ACQUIRE:
+ ipcLockModule_AcquireLock(cid, msg.flags, msg.key);
+ break;
+ case IPC_LOCK_OP_RELEASE:
+ ipcLockModule_ReleaseLock(cid, msg.key);
+ break;
+ default:
+ PR_NOT_REACHED("invalid opcode");
+ }
+}
+
+static void
+ipcLockModule_ClientUp(ipcClientHandle client)
+{
+ LOG(("$$$ ipcLockModule_ClientUp [%u]\n", IPC_GetClientID(client)));
+}
+
+static void
+ipcLockModule_ClientDown(ipcClientHandle client)
+{
+ PRUint32 cid = IPC_GetClientID(client);
+
+ LOG(("$$$ ipcLockModule_ClientDown [%u]\n", cid));
+
+ //
+ // enumerate lock table, release any locks held by this client.
+ //
+
+ PL_HashTableEnumerateEntries(gLockTable, ipcLockModule_ReleaseByCID, &cid);
+}
+
+//-----------------------------------------------------------------------------
+
+static ipcModuleMethods gLockMethods =
+{
+ IPC_MODULE_METHODS_VERSION,
+ ipcLockModule_Init,
+ ipcLockModule_Shutdown,
+ ipcLockModule_HandleMsg,
+ ipcLockModule_ClientUp,
+ ipcLockModule_ClientDown
+};
+
+static ipcModuleEntry gLockModuleEntry[] =
+{
+ { IPC_LOCK_TARGETID, &gLockMethods }
+};
+
+IPC_IMPL_GETMODULES(ipcLockModule, gLockModuleEntry)
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/test/Makefile.in b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/test/Makefile.in
new file mode 100644
index 00000000..bcf9299a
--- /dev/null
+++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/test/Makefile.in
@@ -0,0 +1,67 @@
+# vim:set ts=8 sw=8 noet:
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla IPC.
+#
+# The Initial Developer of the Original Code is IBM Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2004
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Darin Fisher <darin@meer.net>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../../../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = dconnect
+
+REQUIRES = ipcd \
+ nspr \
+ string \
+ xpcom \
+ $(NULL)
+
+CPPSRCS = \
+ TestIPCLocks.cpp \
+ $(NULL)
+
+SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX))
+
+include $(topsrcdir)/config/config.mk
+
+LIBS = \
+ $(EXTRA_DSO_LIBS) \
+ $(XPCOM_LIBS) \
+ $(NSPR_LIBS) \
+ $(NULL)
+
+include $(topsrcdir)/config/rules.mk
diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/test/TestIPCLocks.cpp b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/test/TestIPCLocks.cpp
new file mode 100644
index 00000000..f35e8434
--- /dev/null
+++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/lock/test/TestIPCLocks.cpp
@@ -0,0 +1,244 @@
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla IPC.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This test program spawns N copies of itself, and each copy spawns M threads.
+// Each thread acquires and releases a named, interprocess lock.
+// Randomized delays are injected at various points to exercise the system, and
+// help expose any race conditions that may exist.
+//
+// Usage: TestIPCLocks [-N]
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "ipcILockService.h"
+#include "ipcLockCID.h"
+#include "nsIServiceManagerUtils.h"
+#include "nsIEventQueueService.h"
+#include "nsCOMPtr.h"
+#include "nsXPCOM.h"
+#include "prproces.h"
+#include "prprf.h"
+
+#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
+#include <unistd.h>
+static unsigned GetPID()
+{
+ return (unsigned) getpid();
+}
+#elif defined(XP_WIN)
+#include <windows.h>
+static unsigned GetPID()
+{
+ return (unsigned) GetCurrentProcessId();
+}
+#else
+static unsigned int GetPID()
+{
+ return 0; // implement me!
+}
+#endif
+
+static void LOG(const char *fmt, ... )
+{
+ va_list ap;
+ va_start(ap, fmt);
+ PRUint32 nb = 0;
+ char buf[512];
+
+ nb = PR_snprintf(buf, sizeof(buf), "[%u:%p] ", GetPID(), PR_GetCurrentThread());
+
+ PR_vsnprintf(buf + nb, sizeof(buf) - nb, fmt, ap);
+ buf[sizeof(buf) - 1] = '\0';
+
+ fwrite(buf, strlen(buf), 1, stdout);
+ fflush(stdout);
+
+ va_end(ap);
+}
+
+static void RandomSleep(PRUint32 fromMS, PRUint32 toMS)
+{
+ PRUint32 ms = fromMS + (PRUint32) ((toMS - fromMS) * ((double) rand() / RAND_MAX));
+ //LOG("putting thread to sleep for %u ms\n", ms);
+ PR_Sleep(PR_MillisecondsToInterval(ms));
+}
+
+static ipcILockService *gLockService;
+
+PR_STATIC_CALLBACK(void) TestThread(void *arg)
+{
+ const char *lockName = (const char *) arg;
+
+ LOG("entering TestThread [lock=%s]\n", lockName);
+
+ nsresult rv;
+
+ RandomSleep(1000, 1100);
+
+ //LOG("done sleeping\n");
+
+ rv = gLockService->AcquireLock(lockName, PR_TRUE);
+ if (NS_SUCCEEDED(rv))
+ {
+ //LOG("acquired lock \"%s\"\n", lockName);
+ RandomSleep(500, 1000);
+ //LOG("releasing lock \"%s\"\n", lockName);
+ rv = gLockService->ReleaseLock(lockName);
+ if (NS_FAILED(rv))
+ {
+ LOG("failed to release lock [rv=%x]\n", rv);
+ NS_ERROR("failed to release lock");
+ }
+ }
+ else
+ {
+ LOG("failed to acquire lock [rv=%x]\n", rv);
+ NS_NOTREACHED("failed to acquire lock");
+ }
+
+ LOG("exiting TestThread [lock=%s rv=%x]\n", lockName, rv);
+}
+
+static const char *kLockNames[] = {
+ "foopy",
+ "test",
+ "1",
+ "xyz",
+ "moz4ever",
+ nsnull
+};
+
+static nsresult DoTest()
+{
+ nsresult rv;
+
+ nsCOMPtr<nsIEventQueueService> eqs =
+ do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
+ if (NS_FAILED(rv))
+ return rv;
+
+ rv = eqs->CreateMonitoredThreadEventQueue();
+ if (NS_FAILED(rv))
+ return rv;
+
+ nsCOMPtr<nsIEventQueue> eq;
+ rv = eqs->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(eq));
+ if (NS_FAILED(rv))
+ return rv;
+
+ nsCOMPtr<ipcILockService> lockService =
+ do_GetService(IPC_LOCKSERVICE_CONTRACTID);
+
+ gLockService = lockService;
+
+ PRThread *threads[10] = {0};
+ int i = 0;
+
+ for (const char **lockName = kLockNames; *lockName; ++lockName, ++i)
+ {
+ threads[i] = PR_CreateThread(PR_USER_THREAD,
+ TestThread,
+ (void *) *lockName,
+ PR_PRIORITY_NORMAL,
+ PR_GLOBAL_THREAD,
+ PR_JOINABLE_THREAD,
+ 0);
+ }
+
+ for (i=0; threads[i]; ++i)
+ {
+ PR_JoinThread(threads[i]);
+ threads[i] = nsnull;
+ }
+
+ gLockService = nsnull;
+
+ LOG("joined with all threads; exiting DoTest\n");
+ return NS_OK;
+}
+
+int main(int argc, char **argv)
+{
+ LOG("entering main\n");
+
+ int numProcs = 10;
+
+ // if this is a child process, then just run the test
+ if (argc > 1)
+ {
+ if (strcmp(argv[1], "-child") == 0)
+ {
+ RandomSleep(1000, 1000);
+ LOG("running child test\n");
+ NS_InitXPCOM2(nsnull, nsnull, nsnull);
+ DoTest();
+ NS_ShutdownXPCOM(nsnull);
+ return 0;
+ }
+ else if (argv[1][0] == '-')
+ {
+ // argument is a number
+ numProcs = atoi(argv[1] + 1);
+ if (numProcs == 0)
+ {
+ printf("### usage: TestIPCLocks [-N]\n"
+ "where, N is the number of test processes to spawn.\n");
+ return -1;
+ }
+ }
+ }
+
+ LOG("sleeping for 1 second\n");
+ PR_Sleep(PR_SecondsToInterval(1));
+
+ PRProcess **procs = (PRProcess **) malloc(sizeof(PRProcess*) * numProcs);
+ int i;
+
+ // else, spawn the child processes
+ for (i=0; i<numProcs; ++i)
+ {
+ char *const argv[] = {"./TestIPCLocks", "-child", nsnull};
+ LOG("spawning child test\n");
+ procs[i] = PR_CreateProcess("./TestIPCLocks", argv, nsnull, nsnull);
+ }
+
+ PRInt32 exitCode;
+ for (i=0; i<numProcs; ++i)
+ PR_WaitProcess(procs[i], &exitCode);
+
+ return 0;
+}