genericopenlibs/openenvcore/backend/src/corebackend/localif.cpp
branchRCL_3
changeset 57 2efc27d87e1c
parent 56 acd3cd4aaceb
child 64 c44f36bb61a3
--- a/genericopenlibs/openenvcore/backend/src/corebackend/localif.cpp	Tue Aug 31 16:54:36 2010 +0300
+++ b/genericopenlibs/openenvcore/backend/src/corebackend/localif.cpp	Wed Sep 01 12:36:54 2010 +0100
@@ -82,7 +82,7 @@
 
 // Construction of Backend Object which is going to be singleton object for the process
 EXPORT_C CLocalSystemInterface::CLocalSystemInterface() : iOpenDirList(CLocalSystemInterface::KDirGran),
-iTLDInfoList(CLocalSystemInterface::KTLDInfoListGran), iDefConnPref(NULL)
+iTLDInfoList(CLocalSystemInterface::KTLDInfoListGran), iDefConnResurrect(ETrue), iDefConnPref(NULL)
 		{
 #ifdef SYMBIAN_OE_POSIX_SIGNALS
 		iSignalsInitialized = EFalse;
@@ -183,7 +183,7 @@
 			User::Panic(KEstlibInit, err);
 			}
 
-		iCleanup.StorePtrs(iPrivateHeap, &iFs, &iSs, &iCs, &iSSLock, &iCSLock);
+		iCleanup.StorePtrs(iPrivateHeap, &iFs, &iSs, &iCs, &iSSLock, &iCSLock,&iDefConnLock,&iASelectLock);
 
 		}
 
@@ -194,10 +194,6 @@
 	{
 	iTLDListLock.Close();
 	iSessionPathLock.Close();
-	// Close the aselect lock
-	iASelectLock.Close();
-	// Close the default connection lock
-	iDefConnLock.Close();
 	
 	//close the default RConnection
 	if(iDefConnection.SubSessionHandle() != 0)
@@ -1588,37 +1584,50 @@
 
 	if(!err)
 		{
-		// Check if a connection request is already in progress
-		// for a non-blocking socket.
-		if(f->GetConnectionProgress())
+		// Check if a connection request is already in progress for a non-blocking socket.
+		if (f->GetConnectionProgress())
 			{
-			// Poll to see if the connect() is completed
-			err = f->Poll( EReadyForWriting );
-
-			// The above Poll is common for all descriptors. 
-			// In case of socket-descriptors, Poll will either return "KErrNone"
-			// or any of the requested events. To check for Poll error in case of 
-			// socket-descriptors, "iPollErr" should be checked.			
-			if( (err < 0) || (f->iPollErr < 0) ) //Error in poll
-				(err < 0) ? (mapErr = err):(mapErr = f->iPollErr);
-			else if( err == 0 ) //Connect still in progress
-				mapErr = EALREADY;
-			else if( err & EReadyForWriting ) //Connect has completed
-				f->SetConnectionProgress(EFalse);
+			mapErr = f->iPollErr;
+			
+			if (f->iPollErr < 0)
+			    {
+                mapErr = f->iPollErr;
+                f->iPollErr = 0;
+                f->SetConnectionProgress(EFalse);
+                }
+			else
+			    {
+                // Poll to see if the connect() is completed
+                err = f->Poll(EReadyForWriting);
+                // The above Poll is common for all descriptors. 
+                // In case of socket-descriptors, Poll will either return "KErrNone"
+                // or any of the requested events. To check for Poll error in case of 
+                // socket-descriptors, "iPollErr" should be checked.
+                if (f->iPollErr < 0)
+                    {
+                    mapErr = f->iPollErr;
+                    f->iPollErr = 0;
+                    }
+                else if (err == 0) //Connect still in progress
+                    mapErr = EALREADY;
+                else if (err & EReadyForWriting)
+                    {
+                    mapErr = EISCONN; 
+                    }
+			    }
 			}
 
 		if(!mapErr)
 			{
 			TRequestStatus status;
 			f->Connect(addr,size,status);
-			err=status.Int();
+			err = status.Int();
 
 			if (err == KErrWouldBlock)
 				{
-				f->SetConnectionProgress(ETrue);
 				mapErr = EINPROGRESS;
 				}
-			else if(err == KErrAlreadyExists)
+			else if (err == KErrAlreadyExists)
 				{
 				mapErr = EISCONN;
 				}
@@ -1786,26 +1795,25 @@
 // CLocalSystemInterface::aselect
 // -----------------------------------------------------------------------------
 //
-int CLocalSystemInterface::cancelaselect(TRequestStatus* requeststatus,int& anErrno,int performcleanup)
+int CLocalSystemInterface::cancelaselect(TRequestStatus* requeststatus, int& anErrno, TBool perform_cleanup)
 	{
 	iASelectLock.Wait();
 	// Search for the aselect request entry in the aselect request array
-	for ( TInt i=0; i<iASelectRequest.Count(); i++ )
+	for (TInt i = 0; i < iASelectRequest.Count(); ++i)
 		{
-		if( (iASelectRequest[i].iRequestStatus == requeststatus) || performcleanup )
+		if (iASelectRequest[i].iRequestStatus == requeststatus || perform_cleanup)
 			{
 			// The specified request exists
-			RThread threadHandle;
+			RThread thread;
 			// Open a handle to the service thread
-			TInt res = threadHandle.Open(iASelectRequest[i].iThreadId,EOwnerThread);
-			if( res == KErrNone )
+			TInt res = thread.Open(iASelectRequest[i].iThreadId,EOwnerThread);
+			if (res == KErrNone)
 				{
 				// Kill the service thread
-				threadHandle.Kill(KErrCancel);
-				threadHandle.Close();
-				if( !performcleanup )
+				thread.Kill(KErrCancel);
+				thread.Close();
+				if (!perform_cleanup)
 					{
-					// Complete the request with KErrcancel
 					User::RequestComplete(iASelectRequest[i].iRequestStatus,KErrCancel);
 					}
 				// Switch to backend heap
@@ -1814,15 +1822,15 @@
 				iASelectRequest.Remove(i);
 				// Switch back to old heap
 				User::SwitchHeap(oldHeap);
-				if( !performcleanup )
+				if (!perform_cleanup)
 					{
 					iASelectLock.Signal();
-					return MapError(KErrNone, anErrno);
+					return KErrNone;
 					}
 				}
 			else
 				{
-				if( !performcleanup )
+				if (!perform_cleanup)
 					{
 					iASelectLock.Signal();
 					// unable to open a handle to the service thread
@@ -1833,14 +1841,7 @@
 		}
 	iASelectLock.Signal();
 	// No request found with the specified TRequestStatus object
-	if( !performcleanup )
-		{
-		return MapError(KErrNotFound, anErrno);
-		}
-	else
-		{
-		return MapError(KErrNone, anErrno);
-		}
+	return MapError((!perform_cleanup ? KErrNotFound : KErrNone), anErrno);
 	}
 // -----------------------------------------------------------------------------
 // CLocalSystemInterface::ASelectRequest
@@ -2195,20 +2196,28 @@
         if ( (*reqarray[i]).Int() != KRequestPending ) 
             {
             TInt readyevents = fdesc->TweakReadyEvents((*reqarray[i]).Int());
-            if (readfds && FD_ISSET(reqfds[i], readfds) && (readyevents & EReadyForReading) ) 
+            TInt event_marked = EFalse;
+            if (readfds && FD_ISSET(reqfds[i], readfds) && (readyevents & EReadyForReading)) 
                 { 
                 FD_SET(reqfds[i], &retreadfds); 
-                ++nDescriptorsSet; 
+                ++nDescriptorsSet;
+                event_marked = ETrue;
+
                 }
             if(writefds && FD_ISSET(reqfds[i], writefds) && (readyevents & EReadyForWriting) ) 
                 { 
                 FD_SET(reqfds[i], &retwritefds); 
+
+                event_marked = ETrue;
                 ++nDescriptorsSet; 
                 }
             if(exceptfds && FD_ISSET(reqfds[i], exceptfds) && (readyevents & EAnyException))
                 {
+                if (!fdesc->GetConnectionProgress() || !event_marked)
+                    {
                 FD_SET(reqfds[i], &retexceptfds); 
                 ++nDescriptorsSet;
+                    }
                 }
             }
         else
@@ -3734,11 +3743,11 @@
 	TInt err = KErrNone;
 
 	//Open the database and create the IAP view.
-	CCommsDatabase *apDb = CCommsDatabase::NewL(EDatabaseTypeIAP);
-	CleanupStack::PushL(apDb);
-	apDb->ShowHiddenRecords();
+	CCommsDatabase *iApDb = CCommsDatabase::NewL(EDatabaseTypeIAP);
+	CleanupStack::PushL(iApDb);
+	iApDb->ShowHiddenRecords();
 	//The following pushes the view onto the cleanup stack
-	CCommsDbTableView *view = apDb->OpenTableLC(TPtrC(IAP));
+	CCommsDbTableView *view = iApDb->OpenTableLC(TPtrC(IAP));
 
 	//Iterate through the records to find the matching entry
 	TAccessPointRecord apRecord;
@@ -3754,7 +3763,7 @@
 		}
 
 	CleanupStack::PopAndDestroy(); //Free the view
-	CleanupStack::PopAndDestroy(apDb); //Free the db itself
+	CleanupStack::PopAndDestroy(iApDb); //Free the db itself
 
 	if(err != KErrNone) //Record not found
 		return KErrNotFound;
@@ -3771,8 +3780,8 @@
 // -----------------------------------------------------------------------------
 // CLocalSystemInterface::StartDefConnection
 //
-// Helper function for the setdefaultif() API to restart the 
-// default RConnection with the new settings.
+// Helper function for the setdefaultif() API to start the 
+// default RConnection with/without preferences
 // -----------------------------------------------------------------------------
 //
 TInt CLocalSystemInterface::StartDefConnection()
@@ -3794,6 +3803,42 @@
 	return err;
 	}
 
+TInt CLocalSystemInterface::unsetdefaultif(TBool allow_bringup)
+    {
+    iDefConnLock.Wait();
+    if (iDefConnection.SubSessionHandle() != 0)
+        {
+        TUint count = iSocketArray.Count();            
+        for (TInt i = 0; i < count; ++i)
+            {                
+            iSocketArray[i]->TempClose();
+            }
+        iDefConnection.Close();
+        }
+    
+    RHeap* oheap = User::SwitchHeap(iPrivateHeap);
+    iSocketArray.Reset();
+    
+    if (iDefConnPref)
+        {
+        if (iDefConnPref->ExtensionId() == TConnPref::EConnPrefSnap)
+            {
+            delete (TCommSnapPref*)iDefConnPref;
+            }
+        else
+            {
+            delete (TCommDbConnPref*)iDefConnPref;
+            }
+        }
+    User::SwitchHeap(oheap);
+    
+    iDefConnPref = NULL;
+    iDefConnResurrect = allow_bringup;
+    iDefConnLock.Signal();
+    return KErrNone;
+    }
+
+
 // -----------------------------------------------------------------------------
 // CLocalSystemInterface::setdefaultif
 //
@@ -3802,147 +3847,78 @@
 //
 int CLocalSystemInterface::setdefaultif(const struct ifreq* aIfReq)
     {
-    //If the argument is NULL, close the existing connection
-    if(aIfReq == NULL )
-        {
-        // Obtain lock on the iDefConnection
-        iDefConnLock.Wait();
-
-    if (iDefConnection.SubSessionHandle() != 0)
+    // Do this in any case - whether the argument be a valid pref or NULL
+    iDefConnResurrect = ETrue;
+    
+    // If the argument is NULL, tear down existing connection
+    if (aIfReq == NULL)
         {
-        TUint count = iSocketArray.Count();
-        for (TInt i = 0; i < count; ++i)
-            {                
-            iSocketArray[i]->TempClose();
-            }
-        iDefConnection.Close();        
-        RHeap* oheap = User::SwitchHeap(iPrivateHeap);
-        iSocketArray.Reset();
-        User::SwitchHeap(oheap);
-        }
-
-        if( iDefConnPref )
-            {
-            switch( iDefConnPref->ExtensionId() )
-                {
-                case TConnPref::EConnPrefSnap:
-                    {                    
-                    RHeap* oldHeap = User::SwitchHeap(iPrivateHeap);
-                    delete (TCommSnapPref*)iDefConnPref;
-                    // Switch back to old heap
-                    User::SwitchHeap(oldHeap);
-                    iDefConnPref = NULL;		        
-                    }
-                    break;
-
-                case TConnPref::EConnPrefCommDb:
-                    {
-                    RHeap* oldHeap = User::SwitchHeap(iPrivateHeap);
-                    delete (TCommDbConnPref*)iDefConnPref;
-                    // Switch back to old heap
-                    User::SwitchHeap(oldHeap);
-                    iDefConnPref = NULL;
-                    }
-                    break;		        
-
-                default:
-                    {
-                    iDefConnLock.Signal();
-                    // Unknown type of Connection Pref
-                    return KErrUnknown;
-                    }
-                }
-            }
-        // Release lock on the iDefConnection
-        iDefConnLock.Signal();
-        return KErrNone;
+        return unsetdefaultif();
         }
 
     TPtrC8 namePtr((TText8*)aIfReq->ifr_name);
     TBuf<KCommsDbSvrMaxColumnNameLength> name;
-    TInt err  = CnvUtfConverter::ConvertToUnicodeFromUtf8(name,namePtr);
-    if( err != KErrNone )
+    
+    TInt err = CnvUtfConverter::ConvertToUnicodeFromUtf8(name, namePtr);
+    if (err != KErrNone)
         return err;
-
-    if( iDefConnPref )
+    
+    if (name.Length() == 0)
         {
-        switch( iDefConnPref->ExtensionId() )
+        // interface name is an empty string, SNAP id is specified in ifr_ifru.snap_id
+        if (iDefConnPref && iDefConnPref->ExtensionId() == TConnPref::EConnPrefSnap)
             {
-            case TConnPref::EConnPrefSnap:
-                {
-                RHeap* oldHeap = User::SwitchHeap(iPrivateHeap);
-                delete (TCommSnapPref*)iDefConnPref;
-                // Switch back to old heap
-                User::SwitchHeap(oldHeap);
-                iDefConnPref = NULL;              
-                }
-                break;
-
-            case TConnPref::EConnPrefCommDb:
-                {
-                RHeap* oldHeap = User::SwitchHeap(iPrivateHeap);
-                delete (TCommDbConnPref*)iDefConnPref;
-                // Switch back to old heap
-                User::SwitchHeap(oldHeap);
-                iDefConnPref = NULL;
-                }
-                break;              
-
-            default:
-                {
-                // Unknown type of Connection Pref
-                return KErrUnknown;
-                }
+            ((TCommSnapPref*)iDefConnPref)->SetSnap(aIfReq->ifr_ifru.snap_id);
+            return KErrNone;
             }
-        }
-
-    // If the interface name is an empty string, the SNAP id is to be set 
-    if(name.Length() == 0)
-        {
-        // Switch to backend heap
+        
         RHeap* oldHeap = User::SwitchHeap(iPrivateHeap);
+        delete (TCommDbConnPref*)iDefConnPref; // may be a delete(NULL)
         iDefConnPref = new TCommSnapPref;
-        // Switch back to old heap
         User::SwitchHeap(oldHeap);
-        if( iDefConnPref == NULL )
+
+        if (!iDefConnPref)
             {
             return KErrNoMemory;
             }
-        TCommSnapPref* snapprefptr = (TCommSnapPref*)iDefConnPref;
-        snapprefptr->SetSnap(aIfReq->ifr_ifru.snap_id);
+        
+        ((TCommSnapPref*)iDefConnPref)->SetSnap(aIfReq->ifr_ifru.snap_id);
         return KErrNone;
         }
-    else //Set the IAP name
+    
+    CTrapCleanup *cleanupStack = NULL;
+    
+    // Create a cleanup stack if one doesn't exist
+    if (User::TrapHandler() == NULL)
         {
-        CTrapCleanup *cleanupStack = NULL;
-        //Create a clean up stack if it is not existing.
-        if(User::TrapHandler() == NULL)
-            {
-            cleanupStack = CTrapCleanup::New(); //This will be deleted after use
-            if(cleanupStack == NULL)
-                return KErrNoMemory;
-            }
-
-        // Switch to backend heap
-        RHeap* oldHeap = User::SwitchHeap(iPrivateHeap);
+        cleanupStack = CTrapCleanup::New();
+        if (cleanupStack == NULL)
+            return KErrNoMemory;
+        }
+    
+    if (iDefConnPref && iDefConnPref->ExtensionId() == TConnPref::EConnPrefCommDb)
+        {
+        TRAP(err, (err = GetConnectionPreferencesL(name, *(TCommDbConnPref*)iDefConnPref)));
+        }
+    else
+        {
+        RHeap *oldHeap = User::SwitchHeap(iPrivateHeap);
+        delete (TCommSnapPref*)iDefConnPref;
         iDefConnPref = new TCommDbConnPref;
-        // Switch back to old heap
         User::SwitchHeap(oldHeap);
-        if( iDefConnPref == NULL )
+        
+        if (iDefConnPref)
             {
-            if( cleanupStack != NULL )
-                delete cleanupStack;
-            return KErrNoMemory;
+            TRAP(err, (err = GetConnectionPreferencesL(name, *(TCommDbConnPref*)iDefConnPref)));
             }
-        TRAP(err, (err = GetConnectionPreferencesL(name,*(TCommDbConnPref*)iDefConnPref)))
-
-        if( cleanupStack != NULL )
-            delete cleanupStack;
-
-        return err;
         }
+    
+    delete cleanupStack;
+    
+    return (iDefConnPref ? KErrNone : KErrNoMemory);
     }
 
+
 // -----------------------------------------------------------------------------
 // CLocalSystemInterface::GetDefaultConnection
 //
@@ -3953,16 +3929,16 @@
 RConnection& CLocalSystemInterface::GetDefaultConnection()
     {
     // If GetDefaultConnection is called without calling
-    // setdefaultif then the connection started without any preferences
+    // setdefaultif then the connection is started without any preferences
     // Obtain lock on the iDefConnection
     iDefConnLock.Wait();
-    if(iDefConnection.SubSessionHandle() == 0)
+    if(iDefConnection.SubSessionHandle() == 0 && iDefConnResurrect)
         {
         StartDefConnection();
         }
     // Release lock on the iDefConnection
     iDefConnLock.Signal();
-    return iDefConnection;
+   return iDefConnection;
     }
 
 // -----------------------------------------------------------------------------