Back to index

lightning-sunbird  0.9+nobinonly
Notify.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 //NULL adress
00040 TM_OJIAPITest(ThreadManager_Notify_1) {
00041        GET_TM_FOR_TEST
00042        nsresult rc = threadMgr->Notify(NULL);
00043        if (NS_FAILED(rc))
00044               return TestResult::PASS("Method should fail because adress is invalid (NULL)");
00045        return TestResult::FAIL("Notify", rc);
00046 
00047 }
00048 
00049 //monitor isn't entered by this thread
00050 TM_OJIAPITest(ThreadManager_Notify_2) {
00051        GET_TM_FOR_TEST
00052        nsresult rc = threadMgr->Notify(threadMgr);
00053        if (NS_SUCCEEDED(rc))
00054               return TestResult::PASS("Method should fail because it can call Notify only being monitor's owner.");
00055        return TestResult::FAIL("Notify", rc);
00056 
00057 }
00058 
00059 //monitor is entered by this thread and there are waiting threads
00060 TM_OJIAPITest(ThreadManager_Notify_3) {
00061        GET_TM_FOR_TEST
00062        class DummyThread : public BaseDummyThread {
00063        public:
00064               int notified;
00065               DummyThread(nsIThreadManager *threadMgr, nsresult def_rc) : notified(0) {
00066                      tm = threadMgr;
00067                      rc = def_rc; 
00068               }
00069               NS_METHOD Run() { 
00070                      nsresult lrc = tm->EnterMonitor(tm);
00071                      if (NS_SUCCEEDED(lrc))  {
00072                             //printf("Thread %p is waiting for notify ...\n", this);
00073                             lrc = tm->Wait(tm);
00074                             //if first thread notified it - nsresult rc =ing OK
00075                             if (NS_SUCCEEDED(lrc) && notified)
00076                                    this->rc = NS_OK;
00077                             tm->ExitMonitor(tm);
00078                      } else {
00079                             fprintf(stderr, "ERROR: new thread %p can't create monitor for adress %p\n", this, tm);
00080                      }
00081                      while(1);
00082                      return NS_OK;
00083               }
00084        };
00085        PRUint32 id = 0;
00086        DummyThread *newThread1 = new DummyThread(threadMgr, NS_ERROR_FAILURE);
00087 
00088        nsresult rc  = threadMgr->CreateThread(&id, (nsIRunnable*)newThread1);
00089        if (NS_SUCCEEDED(rc)) {
00090               //give time to new thread to enter monitor and say wait
00091               threadMgr->Sleep((PRUint32)500);
00092               rc = threadMgr->EnterMonitor(threadMgr);
00093               if (NS_SUCCEEDED(rc)) {
00094                      newThread1->notified = 1;
00095                      threadMgr->Notify(threadMgr);
00096                      if (NS_SUCCEEDED(rc)) {
00097                             rc = threadMgr->ExitMonitor(threadMgr);
00098                             if (NS_SUCCEEDED(rc)) {
00099                                    //time to check notified flag and set rc to NS_OK
00100                                    threadMgr->Sleep((PRUint32)500);
00101                                    if (NS_SUCCEEDED(newThread1->rc))
00102                                           return TestResult::PASS("Method should work OK.");
00103                                    return TestResult::FAIL("Notify", rc);           
00104                             } else {
00105                                    return TestResult::FAIL("Notify", "Can't exit monitor", rc);
00106                             }
00107                      } else {
00108                             //can't call Notify method
00109                             return TestResult::FAIL("Notify", rc);
00110                      }
00111               } else {
00112                      return TestResult::FAIL("Notify", "Can't enter monitor", rc);
00113               }
00114        }
00115        //can't create new threds
00116        return TestResult::FAIL("Notify", "Can't create new threads", rc);
00117 }
00118 
00119 
00120 //thread entered monitor but no waiting threads
00121 TM_OJIAPITest(ThreadManager_Notify_4) {
00122        GET_TM_FOR_TEST
00123        nsresult rc = threadMgr->EnterMonitor(threadMgr);
00124        
00125        if (NS_SUCCEEDED(rc)) {
00126               nsresult rc = threadMgr->Notify(threadMgr);
00127               if (NS_SUCCEEDED(rc))
00128                      return TestResult::PASS("Method should work even if there are no other threads waiting on monitor.");
00129               return TestResult::FAIL("Notify", rc);
00130        }
00131        return TestResult::FAIL("Notify", "Can't enter monitor", rc);
00132 }
00133 
00134 
00135 
00136