summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwtc%netscape.com <devnull@localhost>2000-01-04 22:49:28 +0000
committerwtc%netscape.com <devnull@localhost>2000-01-04 22:49:28 +0000
commit0997aa0d8af8618c73573a2fbbabe655e883ec03 (patch)
tree9101ba7db3218fb4c1c6efc6fc04e62b7ac37f65
parentec1e8cc92921ab4e7287108022f0c6c4766604e2 (diff)
downloadnspr-hg-0997aa0d8af8618c73573a2fbbabe655e883ec03.tar.gz
A more efficient implementation for OpenVMS using event flags, contributed
by Colin Blakes <colin@theblakes.com>.
-rw-r--r--pr/src/io/prpolevt.c83
1 files changed, 82 insertions, 1 deletions
diff --git a/pr/src/io/prpolevt.c b/pr/src/io/prpolevt.c
index cd855cdf..744f3aed 100644
--- a/pr/src/io/prpolevt.c
+++ b/pr/src/io/prpolevt.c
@@ -39,6 +39,85 @@
#include "prerror.h"
#include "prlog.h"
+#ifdef VMS
+
+/*
+ * On OpenVMS we use an event flag instead of a pipe or a socket since
+ * event flags are much more efficient on OpenVMS.
+ */
+#include "pprio.h"
+#include <lib$routines.h>
+#include <starlet.h>
+#include <stsdef.h>
+
+PR_IMPLEMENT(PRFileDesc *) PR_NewPollableEvent(void)
+{
+ unsigned int status;
+ int flag = -1;
+ PRFileDesc *event;
+
+ /*
+ ** Allocate an event flag and clear it.
+ */
+ status = lib$get_ef(&flag);
+ if ((!$VMS_STATUS_SUCCESS(status)) || (flag == -1)) {
+ PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, status);
+ return NULL;
+ }
+ sys$clref(flag);
+
+ /*
+ ** Give NSPR the event flag's negative value. We do this because our
+ ** select interprets a negative fd as an event flag rather than a
+ ** regular file fd.
+ */
+ event = PR_CreateSocketPollFd(-flag);
+ if (NULL == event) {
+ lib$free_ef(&flag);
+ return NULL;
+ }
+
+ return event;
+}
+
+PR_IMPLEMENT(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event)
+{
+ int flag = -PR_FileDesc2NativeHandle(event);
+ PR_DestroySocketPollFd(event);
+ lib$free_ef(&flag);
+ return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_SetPollableEvent(PRFileDesc *event)
+{
+ /*
+ ** Just set the event flag.
+ */
+ unsigned int status;
+ status = sys$setef(-PR_FileDesc2NativeHandle(event));
+ if (!$VMS_STATUS_SUCCESS(status)) {
+ PR_SetError(PR_INVALID_ARGUMENT_ERROR, status);
+ return PR_FAILURE;
+ }
+ return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event)
+{
+ /*
+ ** Just clear the event flag.
+ */
+ unsigned int status;
+ status = sys$clref(-PR_FileDesc2NativeHandle(event));
+ if (!$VMS_STATUS_SUCCESS(status)) {
+ PR_SetError(PR_INVALID_ARGUMENT_ERROR, status);
+ return PR_FAILURE;
+ }
+ return PR_SUCCESS;
+}
+
+#else /* VMS */
+
/*
* These internal functions are declared in primpl.h,
* but we can't include primpl.h because the definition
@@ -121,7 +200,7 @@ static PRStatus PR_CALLBACK _pr_PolEvtInit(void)
return PR_SUCCESS;
}
-#if !defined(XP_UNIX) || defined(VMS)
+#if !defined(XP_UNIX)
#define USE_TCP_SOCKETPAIR
#endif
@@ -230,3 +309,5 @@ PR_IMPLEMENT(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event)
return PR_SUCCESS;
}
+
+#endif /* VMS */