Index: pjproject/trunk/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp	(revision 3133)
+++ pjproject/trunk/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp	(revision 3134)
@@ -45,4 +45,5 @@
 #define BITS_PER_SAMPLE			16
 
+
 #if 1
 #   define TRACE_(st) PJ_LOG(3, st)
@@ -414,4 +415,5 @@
     TInt InitRecL();
     TInt StartStreamL();
+    void Deinit();
 
     // Inherited from MQueueHandlerObserver
@@ -420,4 +422,5 @@
     virtual void NotifyError(const TInt aError);
 
+    TBool			 session_opened;
     State			 state_;
     struct aps_stream		*parentStrm_;
@@ -430,6 +433,8 @@
     RMsgQueue<TAPSCommBuffer>    iReadQ;
     RMsgQueue<TAPSCommBuffer>    iReadCommQ;
+    TBool			 readq_opened;
     RMsgQueue<TAPSCommBuffer>    iWriteQ;
     RMsgQueue<TAPSCommBuffer>    iWriteCommQ;
+    TBool			 writeq_opened;
 
     CQueueHandler		*iPlayCommHandler;
@@ -461,7 +466,10 @@
 			       const CPjAudioSetting &setting)
       : MQueueHandlerObserver(rec_cb, play_cb, user_data),
+        session_opened(EFalse),
 	state_(STATE_NULL),
 	parentStrm_(parent_strm),
 	setting_(setting),
+	readq_opened(EFalse),
+	writeq_opened(EFalse),
 	iPlayCommHandler(0),
 	iRecCommHandler(0),
@@ -472,33 +480,6 @@
 CPjAudioEngine::~CPjAudioEngine()
 {
-    Stop();
-
-    delete iRecHandler;
-    delete iPlayCommHandler;
-    delete iRecCommHandler;
-
-    // On some devices, immediate closing after stopping may cause APS server
-    // panic KERN-EXEC 0, so let's wait for sometime before really closing
-    // the client session.
-    TTime start, now;
-    enum { APS_CLOSE_WAIT_TIME = 200 }; /* in msecs */
-    
-    start.UniversalTime();
-    do {
-	pj_symbianos_poll(-1, APS_CLOSE_WAIT_TIME);
-	now.UniversalTime();
-    } while (now.MicroSecondsFrom(start) < APS_CLOSE_WAIT_TIME * 1000);
-
-    iSession.Close();
-
-    if (state_ == STATE_READY) {
-	if (parentStrm_->param.dir != PJMEDIA_DIR_PLAYBACK) {
-	    iReadQ.Close();
-	    iReadCommQ.Close();
-	}
-	iWriteQ.Close();
-	iWriteCommQ.Close();
-    }
-    
+    Deinit();
+
     TRACE_((THIS_FILE, "Sound device destroyed"));
 }
@@ -508,4 +489,5 @@
     TInt err = iSession.InitializePlayer(iPlaySettings);
     if (err != KErrNone) {
+	Deinit();
 	snd_perror("Failed to initialize player", err);
 	return err;
@@ -522,4 +504,6 @@
     while (iWriteCommQ.OpenGlobal(buf3))
 	User::After(10);
+        
+    writeq_opened = ETrue;
 
     // Construct message queue handler
@@ -538,4 +522,5 @@
     TInt err = iSession.InitializeRecorder(iRecSettings);
     if (err != KErrNone && err != KErrAlreadyExists) {
+	Deinit();
 	snd_perror("Failed to initialize recorder", err);
 	return err;
@@ -554,4 +539,6 @@
 	User::After(10);
 
+    readq_opened = ETrue;
+
     // Construct message queue handlers
     iRecHandler = CQueueHandler::NewL(this, &iReadQ, NULL,
@@ -574,4 +561,11 @@
     PJ_ASSERT_RETURN(state_ == STATE_NULL, PJMEDIA_EAUD_INVOP);
     
+    if (!session_opened) {
+	TInt err = iSession.Connect();
+	if (err != KErrNone)
+	    return err;
+	session_opened = ETrue;
+    }
+
     // Even if only capturer are opened, playback thread of APS Server need
     // to be run(?). Since some messages will be delivered via play comm queue.
@@ -593,5 +587,5 @@
 	
 	// Then wait until initialization done.
-	while (state_ != STATE_READY)
+	while (state_ != STATE_READY && state_ != STATE_NULL)
 	    pj_symbianos_poll(-1, 100);
     }
@@ -618,4 +612,5 @@
 
     User::LeaveIfError(iSession.Connect());
+    session_opened = ETrue;
 }
 
@@ -648,4 +643,44 @@
 }
 
+void CPjAudioEngine::Deinit()
+{
+    Stop();
+
+    delete iRecHandler;
+    delete iPlayCommHandler;
+    delete iRecCommHandler;
+
+    if (session_opened) {
+	TTime start, now;
+	enum { APS_CLOSE_WAIT_TIME = 200 }; /* in msecs */
+	
+	// On some devices, immediate closing after stopping may cause 
+	// APS server panic KERN-EXEC 0, so let's wait for sometime before
+	// closing the client session.
+	start.UniversalTime();
+	do {
+	    pj_symbianos_poll(-1, APS_CLOSE_WAIT_TIME);
+	    now.UniversalTime();
+	} while (now.MicroSecondsFrom(start) < APS_CLOSE_WAIT_TIME * 1000);
+
+	iSession.Close();
+	session_opened = EFalse;
+    }
+
+    if (readq_opened) {
+	iReadQ.Close();
+	iReadCommQ.Close();
+	readq_opened = EFalse;
+    }
+
+    if (writeq_opened) {
+	iWriteQ.Close();
+	iWriteCommQ.Close();
+	writeq_opened = EFalse;
+    }
+
+    state_ = STATE_NULL;
+}
+
 void CPjAudioEngine::InputStreamInitialized(const TInt aStatus)
 {
@@ -659,4 +694,6 @@
 	    state_ = STATE_READY;
 	}
+    } else {
+	Deinit();
     }
 }
@@ -676,4 +713,6 @@
 	} else
 	    InitRecL();
+    } else {
+	Deinit();
     }
 }
@@ -681,4 +720,5 @@
 void CPjAudioEngine::NotifyError(const TInt aError)
 {
+    Deinit();
     snd_perror("Error from CQueueHandler", aError);
 }
