Hi,

> November 5th?  I don't see any patches posted to n.p.m.netlib on 
> November 5th (perhaps mozilla is giving me the wrong dates... i don't 
> see it).  What I was referring to was the discussion we were having 
> w.r.t. changes to the patch attached to bug 92928.


this is a resend of the message from November 5th...


Daniel


-------- Original Message --------
Subject: Re: Bug 92928 (Server sockets): New DIFF
Date: Mon, 05 Nov 2001 07:02:41 +0100
From: HackManiac <[EMAIL PROTECTED]>
Organization: Another Netscape Collabra Server User
Newsgroups: netscape.public.mozilla.netlib
References: <[EMAIL PROTECTED]> <[EMAIL PROTECTED]>

Hi,

  > the nsIServerSocket would still need to participate in the same
  > PR_Poll loop, which would mean changes to nsSocketTransportService to
  > work with something other than just nsSocketTransport objects.

one possible (very object oriented) approach to this would be to use a
common base class, that implements just enough to work as a layer
between the nsSocketTransportService and objects that are part of the
work queue. An example is the class nsSocketTransportServiceLayer
located in the nsSocketTransportService.h after applying the patch
attached to this mail.

Although this class inherits nsISupports it should not be available by
calling QueryInterface because the methods are too implementation
dependend (I don't know if this proceeding is acceptable or do we rely
on noboby calling the contained functions???). For this reason the
interface has no IID and the member functions don't follow the calling
conventions for interface methods.

You get a pointer to this layer interface using a static cast on the
super class. The nsISupports is only necessary for the reference
counting during the work queue processing.

Both classes nsSocketTransport and the new nsServerSocket inherit of
this class and implement the pure virtual functions.

This already works fine for the nsSocketTransport class except for the
methods using a static cast to convert a nsITransport pointer into a
nsSocketTransport pointer (this looks a bit critical...)

One of them is nsSocketTransportService::Wakeup().The original
implementation uses the static cast to call
nsSocketTransportService::AddToWorkQ afterwards. The patch's
implementation relies on the fact, that the transport passed to the
Wakeup method has to be in the selection list of
nsSocketTransportService, otherwise a wakeup would not make any sense.
So it traverses all selection list entries to find the
nsSocketTransportServiceLayer that belongs to the i_Transport parameter.
In the worst case that means MAX_OPEN_CONNECTIONS loop passes. But since
this function is rarely used I think this is okay... Other opinions???

The second (and more tricky) method is
nsSocketTransportService::ReuseTransport(). In this case I cannot assume
the requested transport to be in the selection list. The most simple way
(but not my goal, see above) would be to let QueryInterface return the
nsSocketTransportServiceLayer (or a nsISocketTransportServiceLayer
respectively) and call its methods... Suggestions welcome!

If you agree with this basic approach I would start implementing the
server socket support as well.

Thanks,
        Daniel






Index: mozilla/netwerk/base/public/Makefile.in
===================================================================
RCS file: z:/mozilla_cvs/mozilla/netwerk/base/public/Makefile.in,v
retrieving revision 1.62
diff -u -2 -r1.62 Makefile.in
--- mozilla/netwerk/base/public/Makefile.in     3 Oct 2001 00:21:34 -0000       1.62
+++ mozilla/netwerk/base/public/Makefile.in     5 Nov 2001 04:33:31 -0000
@@ -60,4 +60,5 @@
                nsIRequestObserver.idl \
                nsIRequestObserverProxy.idl \
+               nsIServerSocket.idl \
                nsIStreamListener.idl \
                nsIStreamProvider.idl \
Index: mozilla/netwerk/base/public/makefile.win
===================================================================
RCS file: z:/mozilla_cvs/mozilla/netwerk/base/public/makefile.win,v
retrieving revision 1.71
diff -u -2 -r1.71 makefile.win
--- mozilla/netwerk/base/public/makefile.win    3 Oct 2001 00:21:34 -0000       1.71
+++ mozilla/netwerk/base/public/makefile.win    5 Nov 2001 04:34:08 -0000
@@ -56,4 +56,5 @@
         .\nsIRequest.idl                \
         .\nsITransport.idl               \
+        .\nsIServerSocket.idl           \
         .\nsISocketTransport.idl        \
         .\nsISocketTransportService.idl \
Index: mozilla/netwerk/base/public/nsIServerSocket.idl
===================================================================
RCS file: mozilla/netwerk/base/public/nsIServerSocket.idl
diff -N mozilla/netwerk/base/public/nsIServerSocket.idl
--- nul 1 Jan 1970 00:00:00 -0000
+++ mozilla/netwerk/base/public/nsIServerSocket.idl     5 Nov 2001 04:49:54 -0000
@@ -0,0 +1,53 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: NPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Netscape 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/NPL/
+ *
+ * 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.org code.
+ *
+ * The Initial Developer of the Original Code is 
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 NPL, 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 NPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsIRequest.idl"
+
+interface nsISocketTransport;
+
+[scriptable, uuid(6ECB8024-339F-408A-86FC-B35B35840347)]
+interface nsIServerSocket : nsIRequest
+{
+};
+
+[scriptable, uuid(6ECB8025-339F-408A-86FC-B35B35840347)]
+interface nsIServerSocketListener : nsISupports
+{
+    void onNewConnection (in nsIServerSocket server,
+                          in nsISupports ctxt,
+                          in nsISocketTransport connection,
+                          in nsresult status);
+};
Index: mozilla/netwerk/base/public/nsISocketTransportService.idl
===================================================================
RCS file: z:/mozilla_cvs/mozilla/netwerk/base/public/nsISocketTransportService.idl,v
retrieving revision 1.23
diff -u -2 -r1.23 nsISocketTransportService.idl
--- mozilla/netwerk/base/public/nsISocketTransportService.idl   28 Sep 2001 20:08:55 
-0000      1.23
+++ mozilla/netwerk/base/public/nsISocketTransportService.idl   5 Nov 2001 04:50:27 
+-0000
@@ -42,4 +42,6 @@
 interface nsIChannel;
 interface nsIProxyInfo;
+interface nsIServerSocket;
+interface nsIServerSocketListener;
 
 [scriptable, uuid(05331390-6884-11d3-9382-00104ba0fd40)]
@@ -103,4 +105,12 @@
         */
        readonly attribute unsigned long connectedTransportCount;
+
+    nsIServerSocket createServerSocket (in long aPort,
+                                       in nsIServerSocketListener aListener);
+
+    nsIServerSocket createServerSocketOfType (in long Port,
+                                             in nsIServerSocketListener aListener,
+                                              in nsIProxyInfo aProxyInfo);
+
 };
 
Index: mozilla/netwerk/base/src/nsSocketTransport.cpp
===================================================================
RCS file: z:/mozilla_cvs/mozilla/netwerk/base/src/nsSocketTransport.cpp,v
retrieving revision 1.221
diff -u -2 -r1.221 nsSocketTransport.cpp
--- mozilla/netwerk/base/src/nsSocketTransport.cpp      8 Oct 2001 22:17:25 -0000      
 1.221
+++ mozilla/netwerk/base/src/nsSocketTransport.cpp      4 Nov 2001 10:57:51 -0000
@@ -153,10 +153,7 @@
     mClosePending(PR_FALSE),
     mWasConnected(PR_FALSE),
-    mService(nsnull),
     mReadWriteState(0),
-    mSelectFlags(0),
     mStatus(NS_OK),
     mLastOnStatusMsg(0),
-    mSocketFD(nsnull),
     mSocketRef(0),
     mSocketLock(0),
@@ -178,6 +175,4 @@
         gSocketTransportLog = PR_NewLogModule("nsSocketTransport");
 #endif
-    
-    PR_INIT_CLIST(&mListLink);
     
     mLastActiveTime  =  PR_INTERVAL_NO_WAIT;
Index: mozilla/netwerk/base/src/nsSocketTransport.h
===================================================================
RCS file: z:/mozilla_cvs/mozilla/netwerk/base/src/nsSocketTransport.h,v
retrieving revision 1.93
diff -u -2 -r1.93 nsSocketTransport.h
--- mozilla/netwerk/base/src/nsSocketTransport.h        8 Oct 2001 22:17:25 -0000      
 1.93
+++ mozilla/netwerk/base/src/nsSocketTransport.h        5 Nov 2001 05:16:30 -0000
@@ -57,5 +57,6 @@
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIFileStreams.h"
-
+#include "nsSocketTransportService.h"
+ 
 #define NS_SOCKET_TRANSPORT_SEGMENT_SIZE        (2*1024)
 #define NS_SOCKET_TRANSPORT_BUFFER_SIZE         (8*1024)
@@ -143,5 +144,6 @@
 
 class nsSocketTransport : public nsISocketTransport,
-                          public nsIDNSListener
+                          public nsIDNSListener,
+                          public nsSocketTransportServiceLayer
 {
 public:
@@ -155,32 +157,25 @@
     virtual ~nsSocketTransport();
   
-    nsresult Init(nsSocketTransportService* aService,
-                  const char* aHost, 
-                  PRInt32 aPort,
-                     PRUint32 aSocketTypeCount,
-                     const char* *aSocketTypes,
-                  nsIProxyInfo* aProxyInfo,
-                  PRUint32 bufferSegmentSize,
-                  PRUint32 bufferMaxSize);
-    
-    nsresult Process(PRInt16 aSelectFlags);
+    virtual nsresult Init (nsSocketTransportService* aService,
+                           const char* aHost, 
+                           PRInt32 aPort,
+                           PRUint32 aSocketTypeCount,
+                           const char* *aSocketTypes,
+                           nsIProxyInfo* aProxyInfo,
+                           PRUint32 bufferSegmentSize,
+                           PRUint32 bufferMaxSize);
+
+    virtual nsresult Process (PRInt16 aSelectFlags);
+
+    virtual nsresult Cancel (nsresult status);
+
+    virtual nsresult CheckForTimeout (PRIntervalTime aCurrentTime);
+
+    virtual PRBool CanBeReused() { return 
+        (mCurrentState != eSocketState_Error) && !mClosePending;}
 
-    nsresult Cancel(nsresult status);
-    
-    nsresult CheckForTimeout (PRIntervalTime aCurrentTime);
-    
     // Close this socket
     nsresult CloseConnection();
     
-    // Access methods used by the socket transport service...
-    PRFileDesc* GetSocket(void)      { return mSocketFD;    }
-    PRInt16     GetSelectFlags(void) { return mSelectFlags; }
-    PRCList*    GetListNode(void)    { return &mListLink;   }
-    
-    static nsSocketTransport* GetInstance(PRCList* qp) { return 
(nsSocketTransport*)((char*)qp - offsetof(nsSocketTransport, mListLink)); }
-    
-    PRBool CanBeReused() { return 
-        (mCurrentState != eSocketState_Error) && !mClosePending;}
-
     //
     // request helpers
@@ -245,5 +240,4 @@
     PRInt32                         mPort;
     PRIntervalTime                  mLastActiveTime;
-    PRCList                         mListLink;
     PRMonitor*                      mMonitor;
     PRNetAddr                       mNetAddress;
@@ -259,8 +253,5 @@
     PRPackedBool                    mWasConnected;
 
-    nsSocketTransportService*       mService;
-
     PRUint32                        mReadWriteState;
-    PRInt16                         mSelectFlags;
     nsresult                        mStatus;
 
@@ -268,5 +259,4 @@
     nsresult                        mLastOnStatusMsg;
 
-    PRFileDesc*                     mSocketFD;
     PRUint32                        mSocketRef;  // if non-zero, keep the socket open 
unless there is an error
     PRUint32                        mSocketLock; // if non-zero, do not close the 
socket even if there is an error
Index: mozilla/netwerk/base/src/nsSocketTransportService.cpp
===================================================================
RCS file: z:/mozilla_cvs/mozilla/netwerk/base/src/nsSocketTransportService.cpp,v
retrieving revision 1.60
diff -u -2 -r1.60 nsSocketTransportService.cpp
--- mozilla/netwerk/base/src/nsSocketTransportService.cpp       29 Sep 2001 08:27:36 
-0000      1.60
+++ mozilla/netwerk/base/src/nsSocketTransportService.cpp       5 Nov 2001 05:53:41 
+-0000
@@ -40,4 +40,5 @@
 #include "nsSocketTransportService.h"
 #include "nsSocketTransport.h"
+//#include "nsSocketTransportServiceLayer.h"
 #include "nsAutoLock.h"
 #include "nsIIOService.h"
@@ -168,7 +169,7 @@
   //
   if (NS_SUCCEEDED(rv) && !mActiveTransportList) {
-    mActiveTransportList = 
(nsSocketTransport**)PR_Malloc(sizeof(nsSocketTransport*)*MAX_OPEN_CONNECTIONS);
+    mActiveTransportList = 
+(nsSocketTransportServiceLayer**)PR_Malloc(sizeof(nsSocketTransportServiceLayer*)*MAX_OPEN_CONNECTIONS);
     if (mActiveTransportList) {
-      memset(mActiveTransportList, 0, 
sizeof(nsSocketTransport*)*MAX_OPEN_CONNECTIONS);
+      memset(mActiveTransportList, 0, 
+sizeof(nsSocketTransportServiceLayer*)*MAX_OPEN_CONNECTIONS);
     } else {
       rv = NS_ERROR_OUT_OF_MEMORY;
@@ -204,5 +205,5 @@
 }
 
-nsresult nsSocketTransportService::AddToWorkQ(nsSocketTransport* aTransport)
+nsresult nsSocketTransportService::AddToWorkQ(nsSocketTransportServiceLayer* 
+aTransport)
 {
   PRStatus status = PR_SUCCESS;
@@ -260,10 +261,10 @@
   while (!PR_CLIST_IS_EMPTY(&mWorkQ) && 
          (MAX_OPEN_CONNECTIONS > mSelectFDSetCount)) {
-    nsSocketTransport* transport;
+    nsSocketTransportServiceLayer* transport;
 
     // Get the next item off of the workQ...
     qp = PR_LIST_HEAD(&mWorkQ);
 
-    transport = nsSocketTransport::GetInstance(qp);
+    transport = nsSocketTransportServiceLayer::GetInstance(qp);
     PR_REMOVE_AND_INIT_LINK(qp);
 
@@ -301,5 +302,5 @@
 }
 
-nsresult nsSocketTransportService::AddToSelectList(nsSocketTransport* aTransport)
+nsresult nsSocketTransportService::AddToSelectList(nsSocketTransportServiceLayer* 
+aTransport)
 {
   nsresult rv = NS_OK;
@@ -338,5 +339,5 @@
 
 
-nsresult nsSocketTransportService::RemoveFromSelectList(nsSocketTransport* aTransport)
+nsresult 
+nsSocketTransportService::RemoveFromSelectList(nsSocketTransportServiceLayer* 
+aTransport)
 {
   int i;
@@ -432,5 +433,5 @@
     PRInt32 count;
     PRIntervalTime intervalNow;
-    nsSocketTransport* transport;
+    nsSocketTransportServiceLayer* transport;
     int i;
 
@@ -656,12 +657,33 @@
         PRBool * o_Reuse)
 {
-    nsresult rv = NS_ERROR_FAILURE;
+#if 0
+    return NS_ERROR_NOT_IMPLEMENTED;
+#else
+    nsresult rv;
+
+    // TODO: not the same functionality as the original implementation
     if (!i_Transport)
         return NS_ERROR_NULL_POINTER;
-    nsSocketTransport* trans = NS_STATIC_CAST(nsSocketTransport*, 
-        i_Transport);
-    if (!trans) return rv;
-    *o_Reuse = trans->CanBeReused();
-    return NS_OK;
+
+    nsSocketTransportServiceLayer* layer;
+    nsCOMPtr <nsITransport> transport;
+    
+    for (int i = 0; i < mSelectFDSetCount; i++) {
+        layer = mActiveTransportList[i];
+        if (!layer)
+            continue;
+        
+        transport = do_QueryInterface (layer, &rv);
+        if (NS_FAILED (rv))
+            continue;
+
+        if (transport == i_Transport) {
+            *o_Reuse = layer->CanBeReused ();
+            return NS_OK;
+        }
+    }
+
+    return NS_ERROR_FAILURE;
+#endif
 }
 
@@ -673,19 +695,27 @@
 nsSocketTransportService::Wakeup (nsITransport* i_Transport)
 {
-    nsSocketTransport *transport = NS_STATIC_CAST (nsSocketTransport *, i_Transport);
+    nsresult rv;
 
-    if (transport == NULL)
+    if (!i_Transport)
         return NS_ERROR_NULL_POINTER;
 
-    AddToWorkQ (transport);
-
-    if (mThreadEvent)
-        PR_SetPollableEvent (mThreadEvent);
+    nsSocketTransportServiceLayer* layer;
+    nsCOMPtr <nsITransport> transport;
+    
+    for (int i = 0; i < mSelectFDSetCount; i++) {
+        layer = mActiveTransportList[i];
+        if (!layer)
+            continue;
+
+        transport = do_QueryInterface (layer, &rv);
+        if (NS_FAILED (rv))
+            continue;
 
-    // else
-    // XXX/ruslan: normally we would call PR_Interrupt (), but since it did work
-    // wait till NSPR fixes it one day
+        if (transport == i_Transport) {
+            return AddToWorkQ (layer);
+        }
+    }
 
-    return NS_OK;
+    return NS_ERROR_FAILURE;
 }
 
@@ -773,4 +803,21 @@
     *o_TransCount = inUseTransports;
     return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSocketTransportService::CreateServerSocket (PRInt32 aPort,
+                                              nsIServerSocketListener* aListener,
+                                              nsIServerSocket** aResult)
+{
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsSocketTransportService::CreateServerSocketOfType (PRInt32 aPort,
+                                                    nsIServerSocketListener* 
+aListener,
+                                                    nsIProxyInfo* aProxyInfo,
+                                                    nsIServerSocket** aResult)
+{
+    return NS_ERROR_NOT_IMPLEMENTED;
 }
 
Index: mozilla/netwerk/base/src/nsSocketTransportService.h
===================================================================
RCS file: z:/mozilla_cvs/mozilla/netwerk/base/src/nsSocketTransportService.h,v
retrieving revision 1.21
diff -u -2 -r1.21 nsSocketTransportService.h
--- mozilla/netwerk/base/src/nsSocketTransportService.h 28 Sep 2001 20:09:03 -0000     
 1.21
+++ mozilla/netwerk/base/src/nsSocketTransportService.h 5 Nov 2001 05:17:05 -0000
@@ -64,5 +64,5 @@
 
 // Forward declarations...
-class nsSocketTransport;
+class nsSocketTransportServiceLayer;
 
 class nsSocketTransportService : public nsISocketTransportService,
@@ -81,5 +81,5 @@
         Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
     
-    nsresult AddToWorkQ(nsSocketTransport* aTransport);
+    nsresult AddToWorkQ(nsSocketTransportServiceLayer* aTransport);
     
     // XXX: Should these use intervals or Milliseconds?
@@ -90,6 +90,6 @@
     nsresult ProcessWorkQ(void);
     
-    nsresult AddToSelectList(nsSocketTransport* aTransport);
-    nsresult RemoveFromSelectList(nsSocketTransport* aTransport);
+    nsresult AddToSelectList(nsSocketTransportServiceLayer* aTransport);
+    nsresult RemoveFromSelectList(nsSocketTransportServiceLayer* aTransport);
     
     PRInt32   mConnectedTransports;
@@ -108,6 +108,54 @@
     PRInt32               mSelectFDSetCount;
     PRPollDesc*           mSelectFDSet;
-    nsSocketTransport**   mActiveTransportList;
+    nsSocketTransportServiceLayer**   mActiveTransportList;
        nsCOMPtr<nsIStringBundle>   m_stringBundle;
+};
+
+
+class nsSocketTransportServiceLayer :
+    public nsISupports
+{
+public:
+    nsSocketTransportServiceLayer () :
+        mService(nsnull),
+        mSelectFlags(0),
+        mSocketFD(nsnull)
+    {
+        PR_INIT_CLIST(&mListLink);
+    }
+
+    virtual nsresult Init (nsSocketTransportService* aService,
+                           const char* aHost, 
+                           PRInt32 aPort,
+                           PRUint32 aSocketTypeCount,
+                           const char* *aSocketTypes,
+                           nsIProxyInfo* aProxyInfo,
+                           PRUint32 bufferSegmentSize,
+                           PRUint32 bufferMaxSize) = 0;
+
+    virtual nsresult Process (PRInt16 aSelectFlags) = 0;
+
+    virtual nsresult Cancel (nsresult status) = 0;
+
+    virtual nsresult CheckForTimeout (PRIntervalTime aCurrentTime) = 0;
+
+    virtual PRBool CanBeReused () = 0;
+
+    // Access methods used by the socket transport service...
+    PRFileDesc* GetSocket(void)      { return mSocketFD;    }
+    PRInt16     GetSelectFlags(void) { return mSelectFlags; }
+    PRCList*    GetListNode(void)    { return &mListLink;   }
+
+    static nsSocketTransportServiceLayer* GetInstance(PRCList* qp)
+    {
+        return (nsSocketTransportServiceLayer*)((char*)qp - 
+offsetof(nsSocketTransportServiceLayer, mListLink));
+    }
+
+protected:
+    nsSocketTransportService* mService;
+    PRFileDesc*               mSocketFD;
+    PRInt16                   mSelectFlags;
+    PRCList                   mListLink;
+    
 };
 

Reply via email to