Back to index

lightning-sunbird  0.9+nobinonly
nsCacheRequest.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is nsCacheRequest.h, released
00017  * February 22, 2001.
00018  *
00019  * The Initial Developer of the Original Code is
00020  * Netscape Communications Corporation.
00021  * Portions created by the Initial Developer are Copyright (C) 2001
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *   Gordon Sheridan, 22-February-2001
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either the GNU General Public License Version 2 or later (the "GPL"), or
00029  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 
00041 #ifndef _nsCacheRequest_h_
00042 #define _nsCacheRequest_h_
00043 
00044 #include "nspr.h"
00045 #include "nsCOMPtr.h"
00046 #include "nsICache.h"
00047 #include "nsICacheListener.h"
00048 #include "nsIEventQueue.h"
00049 #include "nsCacheSession.h"
00050 
00051 
00052 class nsCacheRequest : public PRCList
00053 {
00054 private:
00055     friend class nsCacheService;
00056     friend class nsCacheEntry;
00057 
00058     nsCacheRequest( nsCString *           key, 
00059                     nsICacheListener *    listener,
00060                     nsCacheAccessMode     accessRequested,
00061                     PRBool                blockingMode,
00062                     nsCacheSession *      session)
00063         : mKey(key),
00064           mInfo(0),
00065           mListener(listener),
00066           mThread(nsnull),
00067           mLock(nsnull),
00068           mCondVar(nsnull)
00069     {
00070         MOZ_COUNT_CTOR(nsCacheRequest);
00071         PR_INIT_CLIST(this);
00072         SetAccessRequested(accessRequested);
00073         SetStoragePolicy(session->StoragePolicy());
00074         if (session->IsStreamBased())             MarkStreamBased();
00075         if (session->WillDoomEntriesIfExpired())  MarkDoomEntriesIfExpired();
00076         if (blockingMode == nsICache::BLOCKING)    MarkBlockingMode();
00077         MarkWaitingForValidation();
00078     }
00079     
00080     ~nsCacheRequest()
00081     {
00082         MOZ_COUNT_DTOR(nsCacheRequest);
00083         delete mKey;
00084         if (mLock)    PR_DestroyLock(mLock);
00085         if (mCondVar) PR_DestroyCondVar(mCondVar);
00086         NS_ASSERTION(PR_CLIST_IS_EMPTY(this), "request still on a list");
00087     }
00088     
00092     enum CacheRequestInfo {
00093         eStoragePolicyMask         = 0x000000FF,
00094         eStreamBasedMask           = 0x00000100,
00095         eDoomEntriesIfExpiredMask  = 0x00001000,
00096         eBlockingModeMask          = 0x00010000,
00097         eWaitingForValidationMask  = 0x00100000,
00098         eAccessRequestedMask       = 0xFF000000
00099     };
00100 
00101     void SetAccessRequested(nsCacheAccessMode mode)
00102     {
00103         NS_ASSERTION(mode <= 0xFF, "too many bits in nsCacheAccessMode");
00104         mInfo &= ~eAccessRequestedMask;
00105         mInfo |= mode << 24;
00106     }
00107 
00108     nsCacheAccessMode AccessRequested()
00109     {
00110         return (nsCacheAccessMode)((mInfo >> 24) & 0xFF);
00111     }
00112 
00113     void MarkStreamBased()      { mInfo |=  eStreamBasedMask; }
00114     PRBool IsStreamBased()      { return (mInfo & eStreamBasedMask) != 0; }
00115 
00116 
00117     void   MarkDoomEntriesIfExpired()   { mInfo |=  eDoomEntriesIfExpiredMask; }
00118     PRBool WillDoomEntriesIfExpired()   { return (mInfo & eDoomEntriesIfExpiredMask); }
00119     
00120     void   MarkBlockingMode()           { mInfo |= eBlockingModeMask; }
00121     PRBool IsBlocking()                 { return  (mInfo & eBlockingModeMask); }
00122     PRBool IsNonBlocking()              { return !(mInfo & eBlockingModeMask); }
00123 
00124     void SetStoragePolicy(nsCacheStoragePolicy policy)
00125     {
00126         NS_ASSERTION(policy <= 0xFF, "too many bits in nsCacheStoragePolicy");
00127         mInfo &= ~eStoragePolicyMask;  // clear storage policy bits
00128         mInfo |= policy;         // or in new bits
00129     }
00130 
00131     nsCacheStoragePolicy StoragePolicy()
00132     {
00133         return (nsCacheStoragePolicy)(mInfo & 0xFF);
00134     }
00135 
00136     void   MarkWaitingForValidation() { mInfo |=  eWaitingForValidationMask; }
00137     void   DoneWaitingForValidation() { mInfo &= ~eWaitingForValidationMask; }
00138     PRBool WaitingForValidation()
00139     {
00140         return (mInfo & eWaitingForValidationMask) != 0;
00141     }
00142 
00143     nsresult
00144     WaitForValidation(void)
00145     {
00146         if (!WaitingForValidation()) {   // flag already cleared
00147             MarkWaitingForValidation();  // set up for next time
00148             return NS_OK;                // early exit;
00149         }
00150 
00151         if (!mLock) {
00152             mLock = PR_NewLock();
00153             if (!mLock) return NS_ERROR_OUT_OF_MEMORY;
00154 
00155             NS_ASSERTION(!mCondVar,"we have mCondVar, but didn't have mLock?");
00156             mCondVar = PR_NewCondVar(mLock);
00157             if (!mCondVar) {
00158                 PR_DestroyLock(mLock);
00159                 return NS_ERROR_OUT_OF_MEMORY;
00160             }
00161         }
00162         PRStatus status = PR_SUCCESS;
00163         PR_Lock(mLock);
00164         while (WaitingForValidation() && (status == PR_SUCCESS) ) {
00165             status = PR_WaitCondVar(mCondVar, PR_INTERVAL_NO_TIMEOUT);
00166         }
00167         MarkWaitingForValidation();  // set up for next time
00168         PR_Unlock(mLock);
00169         
00170         NS_ASSERTION(status == PR_SUCCESS, "PR_WaitCondVar() returned PR_FAILURE?");
00171         if (status == PR_FAILURE)
00172             return NS_ERROR_UNEXPECTED;
00173 
00174         return NS_OK;
00175     }
00176 
00177     void WakeUp(void) {
00178         DoneWaitingForValidation();
00179         if (mLock) {
00180         PR_Lock(mLock);
00181         PR_NotifyCondVar(mCondVar);
00182         PR_Unlock(mLock);
00183         }
00184     }
00185 
00189     nsCString *                mKey;
00190     PRUint32                   mInfo;
00191     nsCOMPtr<nsICacheListener> mListener;
00192     PRThread *                 mThread;
00193     PRLock *                   mLock;
00194     PRCondVar *                mCondVar;
00195 };
00196 
00197 #endif // _nsCacheRequest_h_