(file) Return to Monitor.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

Diff for /pegasus/src/Pegasus/Common/Monitor.cpp between version 1.103.10.20 and 1.110

version 1.103.10.20, 2006/07/19 16:58:52 version 1.110, 2006/06/28 20:58:18
Line 40 
Line 40 
 // //
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
   #include "Network.h"
 #include <Pegasus/Common/Config.h> #include <Pegasus/Common/Config.h>
   
 #include <cstring> #include <cstring>
 #include "Monitor.h" #include "Monitor.h"
 #include "MessageQueue.h" #include "MessageQueue.h"
Line 52 
Line 52 
 #include <Pegasus/Common/Exception.h> #include <Pegasus/Common/Exception.h>
 #include "ArrayIterator.h" #include "ArrayIterator.h"
  
   
   
 //const static DWORD MAX_BUFFER_SIZE = 4096;  // 4 kilobytes  
   
 #ifdef PEGASUS_OS_TYPE_WINDOWS  
 # if defined(FD_SETSIZE) && FD_SETSIZE != 1024  
 #  error "FD_SETSIZE was not set to 1024 prior to the last inclusion \  
 of <winsock.h>. It may have been indirectly included (e.g., by including \  
 <windows.h>). Find inclusion of that header which is visible to this \  
 compilation unit and #define FD_SETZIE to 1024 prior to that inclusion; \  
 otherwise, less than 64 clients (the default) will be able to connect to the \  
 CIMOM. PLEASE DO NOT SUPPRESS THIS WARNING; PLEASE FIX THE PROBLEM."  
   
 # endif  
 # define FD_SETSIZE 1024  
 # include <windows.h>  
 #else  
 # include <sys/types.h>  
 # include <sys/socket.h>  
 # include <sys/time.h>  
 # include <netinet/in.h>  
 # include <netdb.h>  
 # include <arpa/inet.h>  
 #endif  
   
 PEGASUS_USING_STD; PEGASUS_USING_STD;
  
 PEGASUS_NAMESPACE_BEGIN PEGASUS_NAMESPACE_BEGIN
  
 static AtomicInt _connections(0); static AtomicInt _connections(0);
 Mutex Monitor::_cout_mut;  
   
 #ifdef PEGASUS_OS_TYPE_WINDOWS  
  #define PIPE_INCREMENT 1  
 #endif  
  
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
 // //
Line 103 
Line 73 
      _tickle_server_socket(-1),      _tickle_server_socket(-1),
      _tickle_peer_socket(-1)      _tickle_peer_socket(-1)
 { {
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "Entering: Monitor::Monitor(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
     }  
     int numberOfMonitorEntriesToAllocate = MAX_NUMBER_OF_MONITOR_ENTRIES;     int numberOfMonitorEntriesToAllocate = MAX_NUMBER_OF_MONITOR_ENTRIES;
     Socket::initializeInterface();     Socket::initializeInterface();
     _entries.reserveCapacity(numberOfMonitorEntriesToAllocate);     _entries.reserveCapacity(numberOfMonitorEntriesToAllocate);
Line 122 
Line 88 
        _MonitorEntry entry(0, 0, 0);        _MonitorEntry entry(0, 0, 0);
        _entries.append(entry);        _entries.append(entry);
     }     }
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "Exiting:  Monitor::Monitor(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
     }  
 } }
  
 Monitor::~Monitor() Monitor::~Monitor()
 { {
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "Entering: Monitor::~Monitor(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
     }  
     Tracer::trace(TRC_HTTP, Tracer::LEVEL4, "uninitializing interface");     Tracer::trace(TRC_HTTP, Tracer::LEVEL4, "uninitializing interface");
  
     try{     try{
Line 159 
Line 117 
     Socket::uninitializeInterface();     Socket::uninitializeInterface();
     Tracer::trace(TRC_HTTP, Tracer::LEVEL4,     Tracer::trace(TRC_HTTP, Tracer::LEVEL4,
                   "returning from monitor destructor");                   "returning from monitor destructor");
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "Exiting:  Monitor::~Monitor(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
     }  
 } }
  
 void Monitor::initializeTickler(){ void Monitor::initializeTickler(){
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "Entering: Monitor::initializeTickler(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
     }  
     /*     /*
        NOTE: On any errors trying to        NOTE: On any errors trying to
              setup out tickle connection,              setup out tickle connection,
Line 183 
Line 133 
         //handle error         //handle error
         MessageLoaderParms parms("Common.Monitor.TICKLE_CREATE",         MessageLoaderParms parms("Common.Monitor.TICKLE_CREATE",
                                  "Received error number $0 while creating the internal socket.",                                  "Received error number $0 while creating the internal socket.",
 #if !defined(PEGASUS_OS_TYPE_WINDOWS)                                   getSocketError());
                                  errno);  
 #else  
                                  WSAGetLastError());  
 #endif  
         throw Exception(parms);         throw Exception(parms);
     }     }
  
       // set TCP_NODELAY
       int opt = 1;
       setsockopt(_tickle_server_socket, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt));
   
     // initialize the address     // initialize the address
     memset(&_tickle_server_addr, 0, sizeof(_tickle_server_addr));     memset(&_tickle_server_addr, 0, sizeof(_tickle_server_addr));
 #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM
Line 203 
Line 153 
     _tickle_server_addr.sin_family = PF_INET;     _tickle_server_addr.sin_family = PF_INET;
     _tickle_server_addr.sin_port = 0;     _tickle_server_addr.sin_port = 0;
  
     PEGASUS_SOCKLEN_T _addr_size = sizeof(_tickle_server_addr);      SocketLength _addr_size = sizeof(_tickle_server_addr);
  
     // bind server side to socket     // bind server side to socket
     if((::bind(_tickle_server_socket,     if((::bind(_tickle_server_socket,
Line 216 
Line 166 
 #else #else
         MessageLoaderParms parms("Common.Monitor.TICKLE_BIND",         MessageLoaderParms parms("Common.Monitor.TICKLE_BIND",
                                  "Received error number $0 while binding the internal socket.",                                  "Received error number $0 while binding the internal socket.",
 #if !defined(PEGASUS_OS_TYPE_WINDOWS)                                   getSocketError());
                                  errno);  
 #else  
                                  WSAGetLastError());  
 #endif  
 #endif #endif
         throw Exception(parms);         throw Exception(parms);
     }     }
Line 230 
Line 176 
         // handle error         // handle error
         MessageLoaderParms parms("Common.Monitor.TICKLE_LISTEN",         MessageLoaderParms parms("Common.Monitor.TICKLE_LISTEN",
                          "Received error number $0 while listening to the internal socket.",                          "Received error number $0 while listening to the internal socket.",
 #if !defined(PEGASUS_OS_TYPE_WINDOWS)                                   getSocketError());
                                  errno);  
 #else  
                                  WSAGetLastError());  
 #endif  
         throw Exception(parms);         throw Exception(parms);
     }     }
  
Line 246 
Line 188 
         // handle error         // handle error
         MessageLoaderParms parms("Common.Monitor.TICKLE_SOCKNAME",         MessageLoaderParms parms("Common.Monitor.TICKLE_SOCKNAME",
                          "Received error number $0 while getting the internal socket name.",                          "Received error number $0 while getting the internal socket name.",
 #if !defined(PEGASUS_OS_TYPE_WINDOWS)                                   getSocketError());
                                  errno);  
 #else  
                                  WSAGetLastError());  
 #endif  
         throw Exception(parms);         throw Exception(parms);
     }     }
  
Line 261 
Line 199 
         // handle error         // handle error
         MessageLoaderParms parms("Common.Monitor.TICKLE_CLIENT_CREATE",         MessageLoaderParms parms("Common.Monitor.TICKLE_CLIENT_CREATE",
                          "Received error number $0 while creating the internal client socket.",                          "Received error number $0 while creating the internal client socket.",
 #if !defined(PEGASUS_OS_TYPE_WINDOWS)                                   getSocketError());
                                  errno);  
 #else  
                                  WSAGetLastError());  
 #endif  
         throw Exception(parms);         throw Exception(parms);
     }     }
  
       // set TCP_NODELAY
       setsockopt(_tickle_client_socket, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt));
   
     // setup the address of the client     // setup the address of the client
     memset(&_tickle_client_addr, 0, sizeof(_tickle_client_addr));     memset(&_tickle_client_addr, 0, sizeof(_tickle_client_addr));
 #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM
Line 288 
Line 225 
         // handle error         // handle error
         MessageLoaderParms parms("Common.Monitor.TICKLE_CLIENT_BIND",         MessageLoaderParms parms("Common.Monitor.TICKLE_CLIENT_BIND",
                          "Received error number $0 while binding the internal client socket.",                          "Received error number $0 while binding the internal client socket.",
 #if !defined(PEGASUS_OS_TYPE_WINDOWS)                                   getSocketError());
                                  errno);  
 #else  
                                  WSAGetLastError());  
 #endif  
         throw Exception(parms);         throw Exception(parms);
     }     }
  
Line 303 
Line 236 
         // handle error         // handle error
         MessageLoaderParms parms("Common.Monitor.TICKLE_CLIENT_CONNECT",         MessageLoaderParms parms("Common.Monitor.TICKLE_CLIENT_CONNECT",
                          "Received error number $0 while connecting the internal client socket.",                          "Received error number $0 while connecting the internal client socket.",
 #if !defined(PEGASUS_OS_TYPE_WINDOWS)                                   getSocketError());
                                  errno);  
 #else  
                                  WSAGetLastError());  
 #endif  
         throw Exception(parms);         throw Exception(parms);
     }     }
  
     /* set up the slave connection */     /* set up the slave connection */
     memset(&_tickle_peer_addr, 0, sizeof(_tickle_peer_addr));     memset(&_tickle_peer_addr, 0, sizeof(_tickle_peer_addr));
     PEGASUS_SOCKLEN_T peer_size = sizeof(_tickle_peer_addr);      SocketLength peer_size = sizeof(_tickle_peer_addr);
     pegasus_sleep(1);     pegasus_sleep(1);
  
     // this call may fail, we will try a max of 20 times to establish this peer connection     // this call may fail, we will try a max of 20 times to establish this peer connection
Line 340 
Line 269 
         // handle error         // handle error
         MessageLoaderParms parms("Common.Monitor.TICKLE_ACCEPT",         MessageLoaderParms parms("Common.Monitor.TICKLE_ACCEPT",
                          "Received error number $0 while accepting the internal socket connection.",                          "Received error number $0 while accepting the internal socket connection.",
 #if !defined(PEGASUS_OS_TYPE_WINDOWS)                                   getSocketError());
                                  errno);  
 #else  
                                  WSAGetLastError());  
 #endif  
         throw Exception(parms);         throw Exception(parms);
     }     }
     // add the tickler to the list of entries to be monitored and set to IDLE because Monitor only     // add the tickler to the list of entries to be monitored and set to IDLE because Monitor only
Line 352 
Line 277 
     _MonitorEntry entry(_tickle_peer_socket, 1, INTERNAL);     _MonitorEntry entry(_tickle_peer_socket, 1, INTERNAL);
     entry._status = _MonitorEntry::IDLE;     entry._status = _MonitorEntry::IDLE;
     _entries.append(entry);     _entries.append(entry);
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "Exiting:  Monitor::initializeTickler(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
     }  
 } }
  
 void Monitor::tickle(void) void Monitor::tickle(void)
 { {
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "Entering: Monitor::tickle(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
     }  
     static char _buffer[] =     static char _buffer[] =
     {     {
       '0','0'       '0','0'
Line 373 
Line 290 
     Socket::disableBlocking(_tickle_client_socket);     Socket::disableBlocking(_tickle_client_socket);
     Socket::write(_tickle_client_socket,&_buffer, 2);     Socket::write(_tickle_client_socket,&_buffer, 2);
     Socket::enableBlocking(_tickle_client_socket);     Socket::enableBlocking(_tickle_client_socket);
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "Exiting:  Monitor::tickle(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
     }  
 } }
  
 void Monitor::setState( Uint32 index, _MonitorEntry::entry_status status ) void Monitor::setState( Uint32 index, _MonitorEntry::entry_status status )
Line 387 
Line 300 
  
 Boolean Monitor::run(Uint32 milliseconds) Boolean Monitor::run(Uint32 milliseconds)
 { {
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "Entering: Monitor::run(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
     }  
  
     Boolean handled_events = false;     Boolean handled_events = false;
     int i = 0;     int i = 0;
Line 452 
Line 361 
  
                                         if (h._responsePending == true)                                         if (h._responsePending == true)
                                         {                                         {
                         if (!entry.namedPipeConnection)  
                         {  
                             Tracer::trace(TRC_HTTP, Tracer::LEVEL4, "Monitor::run - "                             Tracer::trace(TRC_HTTP, Tracer::LEVEL4, "Monitor::run - "
                                                                                                         "Ignoring connection delete request because "                                                                                                         "Ignoring connection delete request because "
                                                                                                         "responses are still pending. "                                                                                                         "responses are still pending. "
                                                                                                         "connection=0x%p, socket=%d\n",                                                                                                         "connection=0x%p, socket=%d\n",
                                                                                                         (void *)&h, h.getSocket());                                                                                                         (void *)&h, h.getSocket());
                         }  
                         else  
                         {  
                             Tracer::trace(TRC_HTTP, Tracer::LEVEL4, "Monitor::run - "  
                                                                                                         "Ignoring connection delete request because "  
                                                                                                         "responses are still pending. "  
                                                                                                         "connection=0x%p, NamedPipe=%d\n",  
                                                                                                         (void *)&h, h.getNamedPipe().getPipe());  
                         }  
                                                 continue;                                                 continue;
                                         }                                         }
                                         h._connectionClosePending = false;                                         h._connectionClosePending = false;
           MessageQueue &o = h.get_owner();           MessageQueue &o = h.get_owner();
           Message* message;            Message* message= new CloseConnectionMessage(entry.socket);
           if (!entry.namedPipeConnection)  
           {  
               message= new CloseConnectionMessage(entry.socket);  
           }  
           else  
           {  
               message= new CloseConnectionMessage(entry.namedPipe);  
   
           }  
           message->dest = o.getQueueId();           message->dest = o.getQueueId();
  
           // HTTPAcceptor is responsible for closing the connection.           // HTTPAcceptor is responsible for closing the connection.
Line 513 
Line 402 
         place to calculate the max file descriptor (maximum socket number)         place to calculate the max file descriptor (maximum socket number)
         because we have to traverse the entire array.         because we have to traverse the entire array.
     */     */
     //Array<HANDLE> pipeEventArray;      SocketHandle maxSocketCurrentPass = 0;
         PEGASUS_SOCKET maxSocketCurrentPass = 0;      for( int indx = 0; indx < (int)entries.size(); indx++)
     int indx;  
   
   
 #ifdef PEGASUS_OS_TYPE_WINDOWS  
   
     //This array associates named pipe connections to their place in [indx]  
     //in the entries array. The value in poition zero of the array is the  
     //index of the fist named pipe connection in the entries array  
     Array <Uint32> indexPipeCountAssociator;  
     int pipeEntryCount=0;  
     int MaxPipes = PIPE_INCREMENT;  
     HANDLE* hEvents = new HANDLE[PIPE_INCREMENT];  
   
 #endif  
   
     for( indx = 0; indx < (int)entries.size(); indx++)  
     {  
   
   
 #ifdef PEGASUS_OS_TYPE_WINDOWS  
        if(entries[indx].isNamedPipeConnection())  
        {  
   
            //entering this clause mean that a Named Pipe connection is at entries[indx]  
            //cout << "In Monitor::run in clause to to create array of for WaitformultipuleObjects" << endl;  
   
            //cout << "In Monitor::run - pipe being added to array is " << entries[indx].namedPipe.getName() << endl;  
   
             entries[indx].pipeSet = false;  
   
            // We can Keep a counter in the Monitor class for the number of named pipes ...  
            //  Which can be used here to create the array size for hEvents..( obviously before this for loop.:-) )  
             if (pipeEntryCount >= MaxPipes)  
             {  
                // cout << "Monitor::run 'if (pipeEntryCount >= MaxPipes)' begining - pipeEntryCount=" <<  
                    // pipeEntryCount << " MaxPipes=" << MaxPipes << endl;  
                  MaxPipes += PIPE_INCREMENT;  
                  HANDLE* temp_hEvents = new HANDLE[MaxPipes];  
   
                  for (Uint32 i =0;i<pipeEntryCount;i++)  
                  {  
                      temp_hEvents[i] = hEvents[i];  
                  }  
   
                  delete [] hEvents;  
   
                  hEvents = temp_hEvents;  
                 // cout << "Monitor::run 'if (pipeEntryCount >= MaxPipes)' ending"<< endl;  
   
             }  
   
            //pipeEventArray.append((entries[indx].namedPipe.getOverlap()).hEvent);  
            hEvents[pipeEntryCount] = entries[indx].namedPipe.getOverlap()->hEvent;  
   
            indexPipeCountAssociator.append(indx);  
   
     pipeEntryCount++;  
   
   
   
        }  
        else  
   
 #endif  
        {        {
   
            if(maxSocketCurrentPass < entries[indx].socket)            if(maxSocketCurrentPass < entries[indx].socket)
             maxSocketCurrentPass = entries[indx].socket;             maxSocketCurrentPass = entries[indx].socket;
  
Line 589 
Line 413 
                _idleEntries++;                _idleEntries++;
                FD_SET(entries[indx].socket, &fdread);                FD_SET(entries[indx].socket, &fdread);
            }            }
   
        }  
   }   }
  
     /*     /*
Line 606 
Line 428 
     // a socket value.  The original code assumed that the number of sockets     // a socket value.  The original code assumed that the number of sockets
     // and a socket value have the same type.  On Windows they do not.     // and a socket value have the same type.  On Windows they do not.
     //     //
   
     int events;  
     int pEvents;  
   
 #ifdef PEGASUS_OS_TYPE_WINDOWS #ifdef PEGASUS_OS_TYPE_WINDOWS
       int events = select(0, &fdread, NULL, NULL, &tv);
    // events = select(0, &fdread, NULL, NULL, &tv);  
   
     //if (events == NULL)  
     //{  // This connection uses namedPipes  
   
         events = 0;  
         DWORD dwWait=NULL;  
         pEvents = 0;  
   
         {  
         AutoMutex automut(Monitor::_cout_mut);  
         cout << "Monitor::run - Calling WaitForMultipleObjects\n";  
         }  
   
         //this should be in a try block  
   
     dwWait = WaitForMultipleObjects(  
                  MaxPipes,  
                  hEvents,               //ABB:- array of event objects  
                  FALSE,                 // ABB:-does not wait for all  
                  milliseconds);        //ABB:- timeout value   //WW this may need be shorter  
   
     if(dwWait == WAIT_TIMEOUT)  
         {  
         {  
             AutoMutex automut(Monitor::_cout_mut);  
         cout << "Wait WAIT_TIMEOUT\n";  
         cout << "Monitor::run before the select in TIMEOUT clause events = " << events << endl;  
   
         events = select(0, &fdread, NULL, NULL, &tv);  
         cout << "Monitor::run after the select in TIMEOUT clause events = " << events << endl;  
         }  
   
                    // Sleep(2000);  
             //continue;  
   
              //return false;  // I think we do nothing.... Mybe there is a socket connection... so  
              // cant return.  
         }  
         else if (dwWait == WAIT_FAILED)  
         {  
             if (GetLastError() == 6) //WW this may be too specific  
             {  
                 AutoMutex automut(Monitor::_cout_mut);  
                 cout << "Monitor::run about to call 'select since waitForMultipleObjects failed\n";  
                 /********* NOTE  
                 this time (tv) combined with the waitForMulitpleObjects timeout is  
                 too long it will cause the client side to time out  
                 ******************/  
                 events = select(0, &fdread, NULL, NULL, &tv);  
   
             }  
             else  
             {  
                 AutoMutex automut(Monitor::_cout_mut);  
                 cout << "Wait Failed returned\n";  
                 cout << "failed with " << GetLastError() << "." << endl;  
                 pEvents = -1;  
                 return false;  
             }  
         }  
         else  
         {  
             int pCount = dwWait - WAIT_OBJECT_0;  // determines which pipe  
             {  
                  {  
                      AutoMutex automut(Monitor::_cout_mut);  
                      // cout << endl << "****************************" <<  
                      //  "Monitor::run WaitForMultiPleObject returned activity on server pipe: "<<  
                      //  pCount<< endl <<  endl;  
                      cout << "Monitor::run WaitForMultiPleObject returned activity pipeEntrycount is " <<  
                      pipeEntryCount <<  
                      " this is the type " << entries[indexPipeCountAssociator[pCount]]._type << " this is index " << indexPipeCountAssociator[pCount] << endl;  
                  }  
   
                /* There is a timeing problem here sometimes the wite in HTTPConnection i s  
              not all the way done (has not _monitor->setState (_entry_index, _MonitorEntry::IDLE) )  
              there for that should be done here if it is not done alread*/  
   
                if (entries[indexPipeCountAssociator[pCount]]._status.get() != _MonitorEntry::IDLE)  
                {  
                    this->setState(indexPipeCountAssociator[pCount], _MonitorEntry::IDLE);  
                    AutoMutex automut(Monitor::_cout_mut);  
                    cout << "setting state of index " << indexPipeCountAssociator[pCount]  << " to IDLE" << endl;  
                }  
   
   
             }  
   
             pEvents = 1;  
   
             //this statment gets the pipe entry that was trigered  
             entries[indexPipeCountAssociator[pCount]].pipeSet = true;  
   
         }  
 #else #else
     events = select(maxSocketCurrentPass, &fdread, NULL, NULL, &tv);      int events = select(maxSocketCurrentPass, &fdread, NULL, NULL, &tv);
 #endif #endif
     autoEntryMutex.lock();     autoEntryMutex.lock();
     // After enqueue a message and the autoEntryMutex has been released and locked again,     // After enqueue a message and the autoEntryMutex has been released and locked again,
     // the array of _entries can be changed. The ArrayIterator has be reset with the original _entries     // the array of _entries can be changed. The ArrayIterator has be reset with the original _entries
     entries.reset(_entries);     entries.reset(_entries);
  
 #ifdef PEGASUS_OS_TYPE_WINDOWS      if (events == PEGASUS_SOCKET_ERROR)
     if(pEvents == -1)  
     {  
         Tracer::trace(TRC_HTTP, Tracer::LEVEL4,  
           "Monitor::run - errorno = %d has occurred on select.",GetLastError() );  
        // The EBADF error indicates that one or more or the file  
        // descriptions was not valid. This could indicate that  
        // the entries structure has been corrupted or that  
        // we have a synchronization error.  
   
         // We need to generate an assert  here...  
        PEGASUS_ASSERT(GetLastError()!= EBADF);  
   
   
     }  
   
     if(events == SOCKET_ERROR)  
 #else  
     if(events == -1)  
 #endif  
     {     {
   
         Tracer::trace(TRC_HTTP, Tracer::LEVEL4,         Tracer::trace(TRC_HTTP, Tracer::LEVEL4,
           "Monitor::run - errorno = %d has occurred on select.", errno);           "Monitor::run - errorno = %d has occurred on select.", errno);
        // The EBADF error indicates that one or more or the file        // The EBADF error indicates that one or more or the file
Line 746 
Line 449 
  
        PEGASUS_ASSERT(errno != EBADF);        PEGASUS_ASSERT(errno != EBADF);
     }     }
     else if ((events)||(pEvents))      else if (events)
     {  
   
         {         {
                  AutoMutex automut(Monitor::_cout_mut);  
      cout << "IN Monior::run events= " << events << " pEvents= " << pEvents<< endl;  
         }  
   
   
      Tracer::trace(TRC_HTTP, Tracer::LEVEL4,      Tracer::trace(TRC_HTTP, Tracer::LEVEL4,
           "Monitor::run select event received events = %d, monitoring %d idle entries",           "Monitor::run select event received events = %d, monitoring %d idle entries",
            events, _idleEntries);            events, _idleEntries);
        for( int indx = 0; indx < (int)entries.size(); indx++)        for( int indx = 0; indx < (int)entries.size(); indx++)
        {        {
            //cout << "Monitor::run at start of 'for( int indx = 0; indx ' - index = " << indx << endl;  
           // The Monitor should only look at entries in the table that are IDLE (i.e.,           // The Monitor should only look at entries in the table that are IDLE (i.e.,
           // owned by the Monitor).           // owned by the Monitor).
         // cout << endl << " status of entry " << indx << " is " << entries[indx]._status.get() << endl;  
           if((entries[indx]._status.get() == _MonitorEntry::IDLE) &&           if((entries[indx]._status.get() == _MonitorEntry::IDLE) &&
              ((FD_ISSET(entries[indx].socket, &fdread)&& (events)) ||               (FD_ISSET(entries[indx].socket, &fdread)))
              (entries[indx].isNamedPipeConnection() && entries[indx].pipeSet && (pEvents))))  
           {  
   
               {               {
                  AutoMutex automut(Monitor::_cout_mut);               MessageQueue *q = MessageQueue::lookup(entries[indx].queueId);
                  cout <<"Monitor::run - index  " << indx << " just got into 'if' statement" << endl;  
               }  
   
               MessageQueue *q;  
            try{  
   
                  q = MessageQueue::lookup(entries[indx].queueId);  
               }  
              catch (Exception e)  
              {  
                  AutoMutex automut(Monitor::_cout_mut);  
                  cout << " this is what lookup gives - " << e.getMessage() << endl;  
                  exit(1);  
              }  
              catch(...)  
              {  
                  AutoMutex automut(Monitor::_cout_mut);  
                  cout << "MessageQueue::lookup gives strange exception " << endl;  
                  exit(1);  
              }  
   
   
   
   
               Tracer::trace(TRC_HTTP, Tracer::LEVEL4,               Tracer::trace(TRC_HTTP, Tracer::LEVEL4,
                   "Monitor::run indx = %d, queueId =  %d, q = %p",                   "Monitor::run indx = %d, queueId =  %d, q = %p",
                   indx, entries[indx].queueId, q);                   indx, entries[indx].queueId, q);
            //  printf("Monitor::run indx = %d, queueId =  %d, q = %p",  
              //     indx, entries[indx].queueId, q);  
              //cout << "Monitor::run before PEGASUS_ASSerT(q !=0) " << endl;  
              PEGASUS_ASSERT(q !=0);              PEGASUS_ASSERT(q !=0);
  
   
              try              try
              {              {
                 /* {  
                  AutoMutex automut(Monitor::_cout_mut);  
                   cout <<" this is the type " << entries[indx]._type <<  
                       " for index " << indx << endl;  
                cout << "IN Monior::run right before entries[indx]._type == Monitor::CONNECTION" << endl;  
                  }*/  
                if(entries[indx]._type == Monitor::CONNECTION)                if(entries[indx]._type == Monitor::CONNECTION)
                 {                 {
                     {  
                     cout << "In Monitor::run Monitor::CONNECTION clause" << endl;  
                     AutoMutex automut(Monitor::_cout_mut);  
                     }  
   
                                       Tracer::trace(TRC_HTTP, Tracer::LEVEL4,                                       Tracer::trace(TRC_HTTP, Tracer::LEVEL4,
                      "entries[indx].type for indx = %d is Monitor::CONNECTION", indx);                      "entries[indx].type for indx = %d is Monitor::CONNECTION", indx);
                    static_cast<HTTPConnection *>(q)->_entry_index = indx;                    static_cast<HTTPConnection *>(q)->_entry_index = indx;
Line 843 
Line 495 
                    Tracer::trace(TRC_HTTP, Tracer::LEVEL4,                    Tracer::trace(TRC_HTTP, Tracer::LEVEL4,
                          "Monitor::_dispatch: entering run() for indx  = %d, queueId = %d, q = %p",                          "Monitor::_dispatch: entering run() for indx  = %d, queueId = %d, q = %p",
                    dst->_entry_index, dst->_monitor->_entries[dst->_entry_index].queueId, dst);                    dst->_entry_index, dst->_monitor->_entries[dst->_entry_index].queueId, dst);
   
                    /*In the case of named Pipes, the request has already been read from the pipe  
                    therefor this section passed the request data to the HTTPConnection  
                    NOTE: not sure if this would be better suited in a sparate private method  
                    */  
   
                    dst->setNamedPipe(entries[indx].namedPipe); //this step shouldn't be needd  
                    {  
                        AutoMutex automut(Monitor::_cout_mut);  
                    cout << "In Monitor::run after dst->setNamedPipe string read is " <<  entries[indx].namedPipe.raw << endl;  
                    }  
   
                    try                    try
                    {                    {
                        {  
                        AutoMutex automut(Monitor::_cout_mut);  
                        cout << "In Monitor::run about to call 'dst->run(1)' "  << endl;  
                        }  
                        dst->run(1);                        dst->run(1);
                    }                    }
                    catch (...)                    catch (...)
                    {                    {
                        AutoMutex automut(Monitor::_cout_mut);  
                        Tracer::trace(TRC_HTTP, Tracer::LEVEL4,                        Tracer::trace(TRC_HTTP, Tracer::LEVEL4,
                        "Monitor::_dispatch: exception received");                        "Monitor::_dispatch: exception received");
                    }                    }
                    Tracer::trace(TRC_HTTP, Tracer::LEVEL4,                    Tracer::trace(TRC_HTTP, Tracer::LEVEL4,
                    "Monitor::_dispatch: exited run() for index %d", dst->_entry_index);                    "Monitor::_dispatch: exited run() for index %d", dst->_entry_index);
  
                    if (entries[indx].isNamedPipeConnection())  
                    {  
                        entries[indx]._type = Monitor::ACCEPTOR;  
                    }  
   
                    // It is possible the entry status may not be set to busy.                    // It is possible the entry status may not be set to busy.
                    // The following will fail in that case.                    // The following will fail in that case.
                    // PEGASUS_ASSERT(dst->_monitor->_entries[dst->_entry_index]._status.get() == _MonitorEntry::BUSY);                    // PEGASUS_ASSERT(dst->_monitor->_entries[dst->_entry_index]._status.get() == _MonitorEntry::BUSY);
Line 901 
Line 531 
                         // set ourself to BUSY,                         // set ourself to BUSY,
                         // read the data                         // read the data
                         // and set ourself back to IDLE                         // and set ourself back to IDLE
             cout << endl << " in - entries[indx]._type == Monitor::INTERNAL- " << endl << endl;  
             if (!entries[indx].isNamedPipeConnection())  
             {  
                             entries[indx]._status = _MonitorEntry::BUSY;                             entries[indx]._status = _MonitorEntry::BUSY;
                             static char buffer[2];                             static char buffer[2];
                         Socket::disableBlocking(entries[indx].socket);                         Socket::disableBlocking(entries[indx].socket);
Line 911 
Line 539 
                         Socket::enableBlocking(entries[indx].socket);                         Socket::enableBlocking(entries[indx].socket);
                             entries[indx]._status = _MonitorEntry::IDLE;                             entries[indx]._status = _MonitorEntry::IDLE;
             }             }
                 }  
                 else                 else
                 {                 {
             {  
   
             AutoMutex automut(Monitor::_cout_mut);  
             cout << "In Monitor::run else clause of CONNECTION if statments" << endl;  
             }  
   
                                Tracer::trace(TRC_HTTP, Tracer::LEVEL4,                                Tracer::trace(TRC_HTTP, Tracer::LEVEL4,
                      "Non-connection entry, indx = %d, has been received.", indx);                      "Non-connection entry, indx = %d, has been received.", indx);
                    int events = 0;                    int events = 0;
            Message *msg;  
            {  
   
            AutoMutex automut(Monitor::_cout_mut);  
            cout << " In Monitor::run Just before checking if NamedPipeConnection" << "for Index "<<indx<< endl;  
            }  
            if (entries[indx].isNamedPipeConnection())  
            {  
                if(!entries[indx].namedPipe.isConnectionPipe)  
                { /*if we enter this clasue it means that the named pipe that we are  
                    looking at has recived a connection but is not the pipe we get connection requests over.  
                    therefore we need to change the _type to CONNECTION and wait for a CIM Operations request*/  
                    entries[indx]._type = Monitor::CONNECTION;  
   
   
      /* This is a test  - this shows that the read file needs to be done  
      before we call wiatForMultipleObjects*/  
     /******************************************************  
     ********************************************************/  
   
   
   
         memset(entries[indx].namedPipe.raw,'\0',4096);  
         BOOL rc = ::ReadFile(  
                 entries[indx].namedPipe.getPipe(),  
                 &entries[indx].namedPipe.raw,  
                 NAMEDPIPE_MAX_BUFFER_SIZE,  
                 &entries[indx].namedPipe.bytesRead,  
                 entries[indx].namedPipe.getOverlap());  
   
         {  
          AutoMutex automut(Monitor::_cout_mut);  
          cout << "Monitor::run just called read on index " << indx << endl;  
         }  
   
   
          //&entries[indx].namedPipe.bytesRead = &size;  
         if(!rc)  
         {  
             AutoMutex automut(Monitor::_cout_mut);  
            cout << "ReadFile failed for : "  << GetLastError() << "."<< endl;  
   
         }  
   
   
   
     /******************************************************  
     ********************************************************/  
   
   
   
   
                  continue;  
   
   
                }  
                {  
                    AutoMutex automut(Monitor::_cout_mut);  
                     cout << " In Monitor::run about to create a Pipe message" << endl;  
   
                }  
   
                events |= NamedPipeMessage::READ;  
                msg = new NamedPipeMessage(entries[indx].namedPipe, events);  
            }  
            else  
            {  
                {  
                AutoMutex automut(Monitor::_cout_mut);  
                cout << " In Monitor::run ..its a socket message" << endl;  
                }  
                events |= SocketMessage::READ;                events |= SocketMessage::READ;
                        msg = new SocketMessage(entries[indx].socket, events);                     Message *msg = new SocketMessage(entries[indx].socket, events);
            }  
   
                    entries[indx]._status = _MonitorEntry::BUSY;                    entries[indx]._status = _MonitorEntry::BUSY;
                    autoEntryMutex.unlock();                    autoEntryMutex.unlock();
                    q->enqueue(msg);                    q->enqueue(msg);
Line 1007 
Line 555 
            entries.reset(_entries);            entries.reset(_entries);
                    entries[indx]._status = _MonitorEntry::IDLE;                    entries[indx]._status = _MonitorEntry::IDLE;
  
                    {  
                        AutoMutex automut(Monitor::_cout_mut);  
                        PEGASUS_STD(cout) << "Exiting:  Monitor::run(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
                    }  
                    return true;                    return true;
                 }                 }
              }              }
Line 1022 
Line 566 
        }        }
     }     }
  
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "Exiting:  Monitor::run(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
     }  
     return(handled_events);     return(handled_events);
 } }
  
 void Monitor::stopListeningForConnections(Boolean wait) void Monitor::stopListeningForConnections(Boolean wait)
 { {
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "Entering: Monitor::stopListeningForConnections(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
     }  
     PEG_METHOD_ENTER(TRC_HTTP, "Monitor::stopListeningForConnections()");     PEG_METHOD_ENTER(TRC_HTTP, "Monitor::stopListeningForConnections()");
     // set boolean then tickle the server to recognize _stopConnections     // set boolean then tickle the server to recognize _stopConnections
     _stopConnections = 1;     _stopConnections = 1;
Line 1049 
Line 585 
     }     }
  
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "Exiting:  Monitor::stopListeningForConnections(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
     }  
 } }
  
  
 int  Monitor::solicitSocketMessages( int  Monitor::solicitSocketMessages(
     PEGASUS_SOCKET socket,      SocketHandle socket,
     Uint32 events,     Uint32 events,
     Uint32 queueId,     Uint32 queueId,
     int type)     int type)
 { {
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "Entering: Monitor::solicitSocketMessages(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
     }  
    PEG_METHOD_ENTER(TRC_HTTP, "Monitor::solicitSocketMessages");    PEG_METHOD_ENTER(TRC_HTTP, "Monitor::solicitSocketMessages");
    AutoMutex autoMut(_entry_mut);    AutoMutex autoMut(_entry_mut);
    // Check to see if we need to dynamically grow the _entries array    // Check to see if we need to dynamically grow the _entries array
Line 1092 
Line 620 
             _entries[index]._type = type;             _entries[index]._type = type;
             _entries[index]._status = _MonitorEntry::IDLE;             _entries[index]._status = _MonitorEntry::IDLE;
  
             {  
                 AutoMutex automut(Monitor::_cout_mut);  
                 PEGASUS_STD(cout) << "Exiting:  Monitor::solicitSocketMessages(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
             }  
             return index;             return index;
          }          }
       }       }
Line 1105 
Line 629 
    }    }
    _solicitSocketCount--;  // decrease the count, if we are here we didnt do anything meaningful    _solicitSocketCount--;  // decrease the count, if we are here we didnt do anything meaningful
    PEG_METHOD_EXIT();    PEG_METHOD_EXIT();
    {  
        AutoMutex automut(Monitor::_cout_mut);  
        PEGASUS_STD(cout) << "Exiting:  Monitor::solicitSocketMessages(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
    }  
    return -1;    return -1;
  
 } }
  
 void Monitor::unsolicitSocketMessages(PEGASUS_SOCKET socket)  void Monitor::unsolicitSocketMessages(SocketHandle socket)
 { {
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "Entering: Monitor::unsolicitSocketMessages(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
     }  
  
     PEG_METHOD_ENTER(TRC_HTTP, "Monitor::unsolicitSocketMessages");     PEG_METHOD_ENTER(TRC_HTTP, "Monitor::unsolicitSocketMessages");
     AutoMutex autoMut(_entry_mut);     AutoMutex autoMut(_entry_mut);
Line 1152 
Line 668 
         index--;         index--;
     }     }
     PEG_METHOD_EXIT();     PEG_METHOD_EXIT();
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "Exiting:  Monitor::unsolicitSocketMessages(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
     }  
 } }
  
 // Note: this is no longer called with PEP 183. // Note: this is no longer called with PEP 183.
 PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL Monitor::_dispatch(void *parm) PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL Monitor::_dispatch(void *parm)
 { {
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "Entering: Monitor::_dispatch(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
     }  
    HTTPConnection *dst = reinterpret_cast<HTTPConnection *>(parm);    HTTPConnection *dst = reinterpret_cast<HTTPConnection *>(parm);
    Tracer::trace(TRC_HTTP, Tracer::LEVEL4,    Tracer::trace(TRC_HTTP, Tracer::LEVEL4,
         "Monitor::_dispatch: entering run() for indx  = %d, queueId = %d, q = %p",         "Monitor::_dispatch: entering run() for indx  = %d, queueId = %d, q = %p",
Line 1198 
Line 706 
    return 0;    return 0;
 } }
  
   
 //This method is anlogsu to solicitSocketMessages. It does the same thing for named Pipes  
 int  Monitor::solicitPipeMessages(  
     NamedPipe namedPipe,  
     Uint32 events,  //not sure what has to change for this enum  
     Uint32 queueId,  
     int type)  
 {  
    PEG_METHOD_ENTER(TRC_HTTP, "Monitor::solicitPipeMessages");  
    AutoMutex autoMut(_entry_mut);  
    // Check to see if we need to dynamically grow the _entries array  
    // We always want the _entries array to 2 bigger than the  
    // current connections requested  
    PEGASUS_STD(cout) << "In Monitor::solicitPipeMessages at the begining" << PEGASUS_STD(endl);  
   
   
   
    _solicitSocketCount++;  // bump the count  
    int size = (int)_entries.size();  
    if((int)_solicitSocketCount >= (size-1)){  
         for(int i = 0; i < ((int)_solicitSocketCount - (size-1)); i++){  
                 _MonitorEntry entry(0, 0, 0);  
                 _entries.append(entry);  
         }  
    }  
   
    int index;  
    for(index = 1; index < (int)_entries.size(); index++)  
    {  
       try  
       {  
          if(_entries[index]._status.get() == _MonitorEntry::EMPTY)  
          {  
             _entries[index].socket = NULL;  
             _entries[index].namedPipe = namedPipe;  
             _entries[index].namedPipeConnection = true;  
             _entries[index].queueId  = queueId;  
             _entries[index]._type = type;  
             _entries[index]._status = _MonitorEntry::IDLE;  
   
             PEGASUS_STD(cout) << "In Monitor::solicitPipeMessages after seting up  _entries[index] index = " << index << PEGASUS_STD(endl);  
   
             return index;  
          }  
       }  
       catch(...)  
       {  
       }  
   
    }  
    _solicitSocketCount--;  // decrease the count, if we are here we didnt do anything meaningful  
    PEGASUS_STD(cout) << "In Monitor::solicitPipeMessages nothing happed - it didn't work" << PEGASUS_STD(endl);  
   
    PEG_METHOD_EXIT();  
    return -1;  
   
 }  
   
 void Monitor::unsolicitPipeMessages(NamedPipe namedPipe)  
 {  
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "Entering: Monitor::unsolicitPipeMessages(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
     }  
   
     PEG_METHOD_ENTER(TRC_HTTP, "Monitor::unsolicitPipeMessages");  
     AutoMutex autoMut(_entry_mut);  
   
     /*  
         Start at index = 1 because _entries[0] is the tickle entry which never needs  
         to be EMPTY;  
     */  
     unsigned int index;  
     for(index = 1; index < _entries.size(); index++)  
     {  
        if(_entries[index].namedPipe.getPipe() == namedPipe.getPipe())  
        {  
           _entries[index]._status = _MonitorEntry::EMPTY;  
           //_entries[index].namedPipe = PEGASUS_INVALID_SOCKET;  
           _solicitSocketCount--;  
           break;  
        }  
     }  
   
     /*  
         Dynamic Contraction:  
         To remove excess entries we will start from the end of the _entries array  
         and remove all entries with EMPTY status until we find the first NON EMPTY.  
         This prevents the positions, of the NON EMPTY entries, from being changed.  
     */  
     index = _entries.size() - 1;  
     while(_entries[index]._status.get() == _MonitorEntry::EMPTY){  
         if((_entries[index].namedPipe.getPipe() == namedPipe.getPipe()) ||  
             (_entries.size() > MAX_NUMBER_OF_MONITOR_ENTRIES))  
         {  
             _entries.remove(index);  
         }  
         index--;  
     }  
     PEG_METHOD_EXIT();  
     {  
         AutoMutex automut(Monitor::_cout_mut);  
         PEGASUS_STD(cout) << "Exiting:  Monitor::unsolicitPipeMessages(): (tid:" << Uint32(pegasus_thread_self()) << ")" << PEGASUS_STD(endl);  
     }  
 }  
   
   
   
 PEGASUS_NAMESPACE_END PEGASUS_NAMESPACE_END


Legend:
Removed from v.1.103.10.20  
changed lines
  Added in v.1.110

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2