diff options
author | wtc%netscape.com <devnull@localhost> | 2000-01-04 22:49:28 +0000 |
---|---|---|
committer | wtc%netscape.com <devnull@localhost> | 2000-01-04 22:49:28 +0000 |
commit | 0997aa0d8af8618c73573a2fbbabe655e883ec03 (patch) | |
tree | 9101ba7db3218fb4c1c6efc6fc04e62b7ac37f65 | |
parent | ec1e8cc92921ab4e7287108022f0c6c4766604e2 (diff) | |
download | nspr-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.c | 83 |
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 */ |