Back to index

lightning-sunbird  0.9+nobinonly
PostEvent.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  * ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Sun Microsystems, Inc.
00019  * Portions created by the Initial Developer are Copyright (C) 1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 #include <ThreadManagerTests.h>
00038 
00039 #include <nsIEventQueueService.h>
00040 #include <nsIServiceManager.h>
00041 
00042 #include <limits.h>
00043 
00044 
00045 //PostEvent
00046 extern nsIThreadManager* GetThreadManager();
00047 
00048 TM_OJIAPITest(ThreadManager_PostEvent_1) {
00049        GET_TM_FOR_TEST
00050        PRUint32 *id = NULL; 
00051        nsresult rc = threadMgr->PostEvent(*id, NULL, (PRBool)0);
00052        if (NS_FAILED(rc))
00053               return TestResult::PASS("Method should fail because thread's id is specified incorrectly (PRUint32 *id = NULL;)");
00054        return TestResult::FAIL("PostEvent", rc);
00055 
00056 }
00057 
00058 TM_OJIAPITest(ThreadManager_PostEvent_2) {
00059        GET_TM_FOR_TEST
00060        class DummyThread : public BaseDummyThread {
00061        public:              
00062               DummyThread() {}
00063               NS_METHOD Run() { while(1); return NS_OK; }
00064        }; 
00065        PRUint32 id;
00066        DummyThread *dt = new DummyThread();
00067        nsresult rc = threadMgr->CreateThread(&id, dt);
00068               
00069        if (NS_SUCCEEDED(rc)) {
00070               nsresult rc = threadMgr->PostEvent(id, NULL, (PRBool)0);
00071               if (NS_FAILED(rc))
00072                      return TestResult::PASS("Method should fail because no object to be invoked from thread is specified.");
00073               return TestResult::FAIL("PostEvent", rc);
00074        }
00075        return TestResult::FAIL("PostEvent", "Can't create new thread", rc);
00076 
00077 }
00078 
00079 TM_OJIAPITest(ThreadManager_PostEvent_3) {
00080        GET_TM_FOR_TEST
00081        class DummyThread : public BaseDummyThread {
00082        public:              
00083               DummyThread() {}
00084               NS_METHOD Run() { while(1); return NS_OK; }
00085        }; 
00086        PRUint32 id = 0;
00087        DummyThread *dt = new DummyThread();
00088        nsresult rc = threadMgr->CreateThread(&id, dt);
00089               
00090        if (NS_SUCCEEDED(rc)) {
00091               nsresult rc = threadMgr->PostEvent(id, NULL, (PRBool)1);
00092               if (NS_FAILED(rc))
00093                      return TestResult::PASS("Method should fail because no object to be invoked from thread is specified.");
00094               return TestResult::FAIL("PostEvent", rc);
00095        }
00096        return TestResult::FAIL("PostEvent", "Can't create new thread", rc);
00097 
00098 }
00099 
00100 TM_OJIAPITest(ThreadManager_PostEvent_5) {
00101        GET_TM_FOR_TEST
00102        class REvent : public BaseDummyThread {
00103        public:              
00104               REvent() {}
00105               NS_METHOD Run() { return rc = NS_OK; }
00106        }; 
00107        REvent *re = new REvent();
00108        PRThread *pt;
00109               
00110        nsresult rc = threadMgr->PostEvent((PRUint32)pt, re, (PRBool)0);
00111        if (NS_FAILED(rc))
00112               return TestResult::PASS("Method should fail because thtread doesn't exist (PRThread *pt;)");
00113        return TestResult::FAIL("PostEvent", rc);
00114 
00115 }
00116 
00117 TM_OJIAPITest(ThreadManager_PostEvent_6) {
00118        GET_TM_FOR_TEST
00119        class DummyThread : public BaseDummyThread {
00120        public:
00121               PRUint32 id;
00122        public:              
00123               DummyThread(nsIThreadManager *atm, nsresult def_rc) : id(0) {
00124                      rc = def_rc;
00125                      tm = atm;
00126               }
00127               NS_METHOD Run() { 
00128                      nsresult rv, lrc, lrc1;
00129                      static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
00130                      static NS_DEFINE_IID(kIEventQueueServiceIID, NS_IEVENTQUEUESERVICE_IID);
00131                      nsCOMPtr<nsIEventQueueService> eventService = 
00132                               do_GetService(kEventQueueServiceCID, &rv);
00133                      if (NS_FAILED(rv)) nsresult rc = rv;
00134                      nsIEventQueue *nq;
00135 
00136                      nsCOMPtr<nsIEventQueue> eventQueue = NULL;
00137                      
00138                      printf("Waiting for thread ID (%p) ...", &id);
00139                      tm->EnterMonitor(&id);
00140                      tm->ExitMonitor(&id);
00141                      printf("got : %d \n", id);
00142                      lrc = eventService->GetThreadEventQueue((PRThread*)id, getter_AddRefs(eventQueue)); 
00143 
00144                      if (lrc != NS_OK || !eventQueue) {
00145                             printf("Failed to get event queue !\n");
00146                             nsresult rc = NS_ERROR_FAILURE;
00147                      }
00148 
00149                      PRBool eventAvail = (PRBool)0;
00150                      PLEvent *event = NULL;                           
00151                      printf("Try to get an event ... (%d =?)\n", id);
00152                      while(eventQueue->EventAvailable(eventAvail) == NS_OK && eventAvail == PR_FALSE) { }; 
00153                      printf("Event is available - let's handle it !\n");
00154                      eventQueue->GetEvent(&event);
00155                      eventQueue->HandleEvent(event);
00156                      return rc = NS_OK;
00157               }
00158        };
00159 
00160        class REvent : public BaseDummyThread {
00161        private:
00162               nsresult *threadRc;
00163        public:
00164               REvent(nsresult *rc) : threadRc(rc) {}
00165               NS_METHOD Run() { 
00166                      *threadRc = NS_OK;
00167                      printf("Event was handled by thread !\n"); 
00168                      return rc = NS_OK; 
00169               }
00170        };
00171 
00172        PRUint32 id = 0;
00173        DummyThread *dt = new DummyThread(threadMgr, NS_ERROR_FAILURE);
00174        REvent *rEvent = new REvent(&(dt->rc));
00175        threadMgr->EnterMonitor(&(dt->id));
00176        nsresult rc = threadMgr->CreateThread(&id, (nsIRunnable*)dt);
00177 
00178        dt->id = id;
00179        printf("Notifying that id is set (%p => %d) ...\n", &(dt->id), id);
00180        threadMgr->ExitMonitor(&(dt->id));
00181 
00182        if (NS_SUCCEEDED(rc)) {
00183               //let's give time to new thread to create event queue
00184               threadMgr->Sleep((PRUint32)500);
00185               //time to handle the evemt
00186               rc = threadMgr->PostEvent(id, rEvent, (PRBool)1);              
00187               threadMgr->Sleep((PRUint32)500);
00188               if (NS_SUCCEEDED(rc) && NS_SUCCEEDED(dt->rc))
00189                      return TestResult::PASS("Method should work OK.");
00190               return TestResult::FAIL("PostEvent", rc);
00191        }
00192        //printf("Can't create new thread !\n");
00193        return TestResult::FAIL("PostEvent", "Can't create new thread", rc);
00194 }                               
00195 
00196 
00197 TM_OJIAPITest(ThreadManager_PostEvent_7) {
00198        GET_TM_FOR_TEST
00199        class DummyThread : public BaseDummyThread {
00200        public:
00201               PRUint32 id;
00202        public:              
00203               DummyThread(nsIThreadManager *atm, nsresult def_rc) : id(0) {
00204                      rc = def_rc;
00205                      tm = atm;
00206               }
00207               NS_METHOD Run() { 
00208                      nsresult rv, lrc, lrc1;
00209                      static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
00210                      static NS_DEFINE_IID(kIEventQueueServiceIID, NS_IEVENTQUEUESERVICE_IID);
00211                      nsCOMPtr<nsIEventQueueService> eventService = 
00212                               do_GetService(kEventQueueServiceCID, &rv);
00213                      if (NS_FAILED(rv)) nsresult rc = rv;
00214                      nsIEventQueue *nq;
00215 
00216                      nsCOMPtr<nsIEventQueue> eventQueue = NULL;
00217                      
00218                      //tm->EnterMonitor(&id);
00219                      printf("Waiting for thread ID (%p) ...", &id);
00220                      while(!id);
00221                      //tm->Wait(&id);
00222                      printf("got : %d \n", id);
00223                      lrc = eventService->GetThreadEventQueue((PRThread*)id, getter_AddRefs(eventQueue)); 
00224 
00225                      if (lrc != NS_OK || !eventQueue) {
00226                             printf("Failed to get event queue !\n");
00227                             nsresult rc = NS_ERROR_FAILURE;
00228                      }
00229 
00230                      PRBool eventAvail = (PRBool)0;
00231                      PLEvent *event = NULL;                           
00232                      printf("Try to get an event ... (%d =?)\n", id);
00233                      while(eventQueue->EventAvailable(eventAvail) == NS_OK && eventAvail == PR_FALSE) { tm->Sleep(3000); } 
00234                      printf("Event is available - let's handle it !\n");
00235                      eventQueue->GetEvent(&event);
00236                      eventQueue->HandleEvent(event);
00237                      return rc = NS_OK;
00238               }
00239        };
00240 
00241        class REvent : public BaseDummyThread {
00242        private:
00243               nsresult *threadRc;
00244        public:
00245               REvent(nsresult *rc) : threadRc(rc) {}
00246               NS_METHOD Run() { 
00247                      *threadRc = NS_OK;
00248                      printf("Event was handled by thread !\n"); 
00249                      return rc = NS_OK; 
00250               }
00251        };
00252 
00253        PRUint32 id = 0;
00254        DummyThread *dt = new DummyThread(threadMgr, NS_ERROR_FAILURE);
00255        REvent *rEvent = new REvent(&(dt->rc));
00256        threadMgr->EnterMonitor(&(dt->id));
00257        nsresult rc = threadMgr->CreateThread(&id, (nsIRunnable*)dt);
00258 
00259        dt->id = id;
00260        printf("Notifying that id is set (%p => %d) ...\n", &(dt->id), id);
00261        threadMgr->NotifyAll(&(dt->id));
00262        threadMgr->ExitMonitor(&(dt->id));
00263 
00264        if (NS_SUCCEEDED(rc)) {
00265               //let's give time to new thread to create event queue
00266               threadMgr->Sleep((PRUint32)500);
00267               //time to handle the evemt
00268               rc = threadMgr->PostEvent(id, rEvent, (PRBool)0);              
00269               threadMgr->Sleep((PRUint32)500);
00270               if (NS_SUCCEEDED(rc) && NS_SUCCEEDED(dt->rc))
00271                      return TestResult::PASS("Method should work OK.");
00272               //printf("Event wasn't handled by thread (so we didn't wait for result) !\n");
00273               return TestResult::FAIL("PostEvent", "Event wasn't handled by thread (so we didn't wait for result)", rc);
00274        }
00275        printf("Can't create new thread !\n");
00276        return TestResult::FAIL("PostEvent", "Can't create new thread", rc);
00277        
00278 }                               
00279 
00280 
00281