Bug 888581 - Allow integrating NSPR/NSS sockets into non-NSPR event loops, Add PR_SocketPollingStatus(), r=rrelyea
authorMiloslav Trmač <mitr@redhat.com>
Tue, 22 Oct 2013 23:06:44 +0200
changeset 4483 77c4ee30c1feead289574946e678883836bb3a43
parent 4482 1bd2f00745d3331562fcc89eddc69d445eb92c89
child 4484 9b26e99c21c37c97d3ca286c3ac96e2fd82e980d
push id33
push userkaie@kuix.de
push dateTue, 22 Oct 2013 21:07:05 +0000
reviewersrrelyea
bugs888581
Bug 888581 - Allow integrating NSPR/NSS sockets into non-NSPR event loops, Add PR_SocketPollingStatus(), r=rrelyea
pr/include/prio.h
pr/src/io/prsocket.c
pr/src/pthreads/ptio.c
--- a/pr/include/prio.h
+++ b/pr/include/prio.h
@@ -2006,27 +2006,61 @@ typedef __int64 PROsfd;
 #else
 typedef PRInt32 PROsfd;
 #endif
 
 /*
  ************************************************************************
  * FUNCTION:    PR_SocketPollingHandle
  * DESCRIPTION:
- * Return an OS native file handle of a socket, suitable for poll() or select().
+ * Return an OS native file handle of a socket, suitable for poll() or select()
+ * together with flags based on the result of PR_SocketPollingStatus().
  * The caller must not use the file handle for anything else.
  *
+ * This function is intended for easier integration of PRFileDesc objects into
+ * a non-NSPR event loop; native NSPR applications do not need to call this.
+ *
  * INPUTS:
  *     PRFileDesc *fd
  *       Points to a PRFileDesc object representing a socket.
  * OUTPUTS:    None
  * RETURN:
  *     PROsfd
  *        An OS native file handle suitable for poll() or select() (if provided
  *        by the OS), or -1 on failure.  The handle must not be closed by the
  *        caller, it will be automatically invalidated by PR_Close(fd).
  ************************************************************************
  */
 NSPR_API(PROsfd) PR_SocketPollingHandle(PRFileDesc *fd);
 
+/*
+ ************************************************************************
+ * FUNCTION:    PR_SocketPollingStatus
+ * DESCRIPTION:
+ * Check whether specified operation is ready on a socket, and if not,
+ * what operation to wait for on the underlying OS socket returned by
+ * PR_SocketPollingHandle() (which can differ from the application-requested
+ * operation, e.g. during TLS renegotiation).
+ *
+ * This function is intended for easier integration of PRFileDesc objects into
+ * a non-NSPR event loop; native NSPR applications do not need to call this.
+ *
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       Points to a PRFileDesc object representing a socket.
+ *     PRInt16 in_flags
+ *       PR_POLL_* flags for operations the caller wants to wait for.
+ * OUTPUTS:
+ *     PRInt16 *out_flags
+ *       PR_POLL_* flags for operations that are already available.
+ * RETURN:
+ *     PRInt32
+ *       PR_POLL_* flags (NOT native POLL* flags) for operations the caller
+ *       should wait for on the underlying OS socket.  On failure, the value
+ *       is -1.
+ ************************************************************************
+ */
+NSPR_API(PRInt32) PR_SocketPollingStatus(PRFileDesc *fd, PRInt16 in_flags,
+    PRInt16 *out_flags);
+
 PR_END_EXTERN_C
 
 #endif /* prio_h___ */
--- a/pr/src/io/prsocket.c
+++ b/pr/src/io/prsocket.c
@@ -1558,16 +1558,29 @@ PR_SocketPollingHandle(PRFileDesc *fd)
 
 PR_IMPLEMENT(void)
 PR_ChangeFileDescNativeHandle(PRFileDesc *fd, PROsfd handle)
 {
 	if (fd)
 		fd->secret->md.osfd = handle;
 }
 
+PR_IMPLEMENT(PRInt32)
+PR_SocketPollingStatus(PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    if (fd == NULL)
+    {
+         PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+         return -1;
+    }
+    /* Should this refuse a non-socket fd? */
+    return (fd->methods->poll)(fd, in_flags, out_flags);
+}
+
 /*
 ** Select compatibility
 **
 */
 
 PR_IMPLEMENT(void) PR_FD_ZERO(PR_fd_set *set)
 {
 	memset(set, 0, sizeof(PR_fd_set));
--- a/pr/src/pthreads/ptio.c
+++ b/pr/src/pthreads/ptio.c
@@ -4640,16 +4640,29 @@ PR_IMPLEMENT(PROsfd) PR_SocketPollingHan
 }  /* PR_SocketPollingHandle */
 
 PR_IMPLEMENT(void) PR_ChangeFileDescNativeHandle(PRFileDesc *fd,
     PRInt32 handle)
 {
     if (fd) fd->secret->md.osfd = handle;
 }  /*  PR_ChangeFileDescNativeHandle*/
 
+PR_IMPLEMENT(PRInt32) PR_SocketPollingStatus(PRFileDesc *fd, PRInt16 in_flags,
+    PRInt16 *out_flags)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    if (fd == NULL)
+    {
+         PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+         return -1;
+    }
+    /* Should this refuse a non-socket fd? */
+    return (fd->methods->poll)(fd, in_flags, out_flags);
+}
+
 PR_IMPLEMENT(PRStatus) PR_LockFile(PRFileDesc *fd)
 {
     PRStatus status = PR_SUCCESS;
 
     if (pt_TestAbort()) return PR_FAILURE;
 
     PR_Lock(_pr_flock_lock);
     while (-1 == fd->secret->lockCount)