Ejemplo n.º 1
0
nsresult nsCacheEntryDescriptor::
nsInputStreamWrapper::LazyInit()
{
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSINPUTSTREAMWRAPPER_LAZYINIT));

    nsCacheAccessMode mode;
    nsresult rv = mDescriptor->GetAccessGranted(&mode);
    if (NS_FAILED(rv)) return rv;

    NS_ENSURE_TRUE(mode & nsICache::ACCESS_READ, NS_ERROR_UNEXPECTED);

    nsCacheEntry* cacheEntry = mDescriptor->CacheEntry();
    if (!cacheEntry) return NS_ERROR_NOT_AVAILABLE;

    rv = nsCacheService::OpenInputStreamForEntry(cacheEntry, mode,
                                                 mStartOffset,
                                                 getter_AddRefs(mInput));

    CACHE_LOG_DEBUG(("nsInputStreamWrapper::LazyInit "
                      "[entry=%p, wrapper=%p, mInput=%p, rv=%d]",
                      mDescriptor, this, mInput.get(), int(rv)));

    if (NS_FAILED(rv)) return rv;

    mInitialized = true;
    return NS_OK;
}
NS_INTERFACE_MAP_END_THREADSAFE

nsresult nsCacheEntryDescriptor::
nsInputStreamWrapper::LazyInit()
{
    // Check if we have the descriptor. If not we can't even grab the cache
    // lock since it is not ensured that the cache service still exists.
    if (!mDescriptor)
        return NS_ERROR_NOT_AVAILABLE;

    nsCacheServiceAutoLock lock(LOCK_TELEM(NSINPUTSTREAMWRAPPER_LAZYINIT));

    nsCacheAccessMode mode;
    nsresult rv = mDescriptor->GetAccessGranted(&mode);
    if (NS_FAILED(rv)) return rv;

    NS_ENSURE_TRUE(mode & nsICache::ACCESS_READ, NS_ERROR_UNEXPECTED);

    nsCacheEntry* cacheEntry = mDescriptor->CacheEntry();
    if (!cacheEntry) return NS_ERROR_NOT_AVAILABLE;

    rv = nsCacheService::OpenInputStreamForEntry(cacheEntry, mode,
                                                 mStartOffset,
                                                 getter_AddRefs(mInput));

    CACHE_LOG_DEBUG(("nsInputStreamWrapper::LazyInit "
                      "[entry=%p, wrapper=%p, mInput=%p, rv=%d]",
                      mDescriptor, this, mInput.get(), int(rv)));

    if (NS_FAILED(rv)) return rv;

    mInitialized = true;
    return NS_OK;
}
Ejemplo n.º 3
0
NS_IMETHODIMP
nsCacheEntryDescriptor::OpenOutputStream(uint32_t offset, nsIOutputStream ** result)
{
    NS_ENSURE_ARG_POINTER(result);

    {
        nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_OPENOUTPUTSTREAM));
        if (!mCacheEntry)                  return NS_ERROR_NOT_AVAILABLE;
        if (!mCacheEntry->IsStreamData())  return NS_ERROR_CACHE_DATA_IS_NOT_STREAM;

        // ensure valid permissions
        if (!(mAccessGranted & nsICache::ACCESS_WRITE))
            return NS_ERROR_CACHE_WRITE_ACCESS_DENIED;
    }

    nsOutputStreamWrapper* cacheOutput = nullptr;
    int32_t compressionLevel = nsCacheService::CacheCompressionLevel();
    const char *val;
    val = mCacheEntry->GetMetaDataElement("uncompressed-len");
    if ((compressionLevel > 0) && val) {
        cacheOutput = new nsCompressOutputStreamWrapper(this, offset);
    } else {
        // clear compression flag when compression disabled - see bug #715198
        if (val) {
            mCacheEntry->SetMetaDataElement("uncompressed-len", nullptr);
        }
        cacheOutput = new nsOutputStreamWrapper(this, offset);
    }
    if (!cacheOutput) return NS_ERROR_OUT_OF_MEMORY;

    NS_ADDREF(*result = cacheOutput);
    return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::OpenInputStream(uint32_t offset, nsIInputStream ** result)
{
    NS_ENSURE_ARG_POINTER(result);

    nsInputStreamWrapper* cacheInput = nullptr;
    {
        nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_OPENINPUTSTREAM));
        if (!mCacheEntry)                  return NS_ERROR_NOT_AVAILABLE;
        if (!mCacheEntry->IsStreamData())  return NS_ERROR_CACHE_DATA_IS_NOT_STREAM;

        // Don't open any new stream when closing descriptor or clearing entries
        if (mClosingDescriptor || nsCacheService::GetClearingEntries())
            return NS_ERROR_NOT_AVAILABLE;

        // ensure valid permissions
        if (!(mAccessGranted & nsICache::ACCESS_READ))
            return NS_ERROR_CACHE_READ_ACCESS_DENIED;

        const char *val;
        val = mCacheEntry->GetMetaDataElement("uncompressed-len");
        if (val) {
            cacheInput = new nsDecompressInputStreamWrapper(this, offset);
        } else {
            cacheInput = new nsInputStreamWrapper(this, offset);
        }
        if (!cacheInput) return NS_ERROR_OUT_OF_MEMORY;

        mInputWrappers.AppendElement(cacheInput);
    }

    NS_ADDREF(*result = cacheInput);
    return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::Doom()
{
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_DOOM));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    return nsCacheService::DoomEntry(mCacheEntry);
}
NS_IMETHODIMP
nsCacheEntryDescriptor::GetKey(nsACString &result)
{
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_GETKEY));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    return ClientKeyFromCacheKey(*(mCacheEntry->Key()), result);
}
NS_IMETHODIMP
nsCacheEntryDescriptor::DoomAndFailPendingRequests(nsresult status)
{
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_DOOMANDFAILPENDINGREQUESTS));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::Close()
{
    nsRefPtr<nsOutputStreamWrapper> outputWrapper;
    nsTArray<nsRefPtr<nsInputStreamWrapper> > inputWrappers;

    {
        nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_CLOSE));
        if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

        // Make sure no other stream can be opened
        mClosingDescriptor = true;
        outputWrapper = mOutputWrapper;
        for (int32_t i = 0 ; i < mInputWrappers.Count() ; i++)
            inputWrappers.AppendElement(static_cast<nsInputStreamWrapper *>(
                        mInputWrappers[i]));
    }

    // Call Close() on the streams outside the lock since it might need to call
    // methods that grab the cache service lock, e.g. compressed output stream
    // when it finalizes the entry
    if (outputWrapper) {
        if (NS_FAILED(outputWrapper->Close())) {
            NS_WARNING("Dooming entry because Close() failed!!!");
            Doom();
        }
        outputWrapper = nullptr;
    }

    for (uint32_t i = 0 ; i < inputWrappers.Length() ; i++)
        inputWrappers[i]->Close();

    inputWrappers.Clear();

    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_CLOSE));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    // XXX perhaps closing descriptors should clear/sever transports

    // tell nsCacheService we're going away
    nsCacheService::CloseDescriptor(this);
    NS_ASSERTION(mCacheEntry == nullptr, "mCacheEntry not null");

    return NS_OK;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::GetFile(nsIFile ** result)
{
    NS_ENSURE_ARG_POINTER(result);
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_GETFILE));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    return nsCacheService::GetFileForEntry(mCacheEntry, result);
}
Ejemplo n.º 10
0
NS_IMETHODIMP nsCacheEntryDescriptor::SetPredictedDataSize(int64_t
                                                           predictedSize)
{
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_SETPREDICTEDDATASIZE));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    mCacheEntry->SetPredictedDataSize(predictedSize);
    return NS_OK;
}
Ejemplo n.º 11
0
NS_IMETHODIMP
nsCacheEntryDescriptor::SetCacheElement(nsISupports * cacheElement)
{
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_SETCACHEELEMENT));
    if (!mCacheEntry)                 return NS_ERROR_NOT_AVAILABLE;
    if (mCacheEntry->IsStreamData())  return NS_ERROR_CACHE_DATA_IS_STREAM;

    return nsCacheService::SetCacheElement(mCacheEntry, cacheElement);
}
Ejemplo n.º 12
0
NS_IMETHODIMP nsCacheEntryDescriptor::GetPredictedDataSize(int64_t *result)
{
    NS_ENSURE_ARG_POINTER(result);
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_GETPREDICTEDDATASIZE));
    if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;

    *result = mCacheEntry->PredictedDataSize();
    return NS_OK;
}
Ejemplo n.º 13
0
NS_IMETHODIMP
nsCacheEntryDescriptor::MarkValid()
{
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_MARKVALID));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    nsresult  rv = nsCacheService::ValidateEntry(mCacheEntry);
    return rv;
}
Ejemplo n.º 14
0
NS_IMETHODIMP nsCacheEntryDescriptor::IsStreamBased(bool *result)
{
    NS_ENSURE_ARG_POINTER(result);
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_ISSTREAMBASED));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    *result = mCacheEntry->IsStreamData();
    return NS_OK;
}
Ejemplo n.º 15
0
NS_IMETHODIMP
nsCacheEntryDescriptor::GetStoragePolicy(nsCacheStoragePolicy *result)
{
    NS_ENSURE_ARG_POINTER(result);
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_GETSTORAGEPOLICY));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;
    
    *result = mCacheEntry->StoragePolicy();
    return NS_OK;
}
Ejemplo n.º 16
0
NS_IMETHODIMP
nsCacheEntryDescriptor::GetClientID(char ** result)
{
    NS_ENSURE_ARG_POINTER(result);

    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_GETCLIENTID));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    return ClientIDFromCacheKey(*(mCacheEntry->Key()), result);
}
Ejemplo n.º 17
0
NS_IMETHODIMP
nsCacheEntryDescriptor::GetFetchCount(int32_t *result)
{
    NS_ENSURE_ARG_POINTER(result);
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_GETFETCHCOUNT));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    *result = mCacheEntry->FetchCount();
    return NS_OK;
}
Ejemplo n.º 18
0
NS_IMETHODIMP nsCacheEntryDescriptor::GetStorageDataSize(uint32_t *result)
{
    NS_ENSURE_ARG_POINTER(result);
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_GETSTORAGEDATASIZE));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    *result = mCacheEntry->DataSize();

    return NS_OK;
}
Ejemplo n.º 19
0
NS_IMETHODIMP
nsCacheEntryDescriptor::GetLastModified(uint32_t *result)
{
    NS_ENSURE_ARG_POINTER(result);
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_GETLASTMODIFIED));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    *result = mCacheEntry->LastModified();
    return NS_OK;
}
Ejemplo n.º 20
0
NS_IMETHODIMP
nsCacheEntryDescriptor::GetExpirationTime(uint32_t *result)
{
    NS_ENSURE_ARG_POINTER(result);
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_GETEXPIRATIONTIME));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    *result = mCacheEntry->ExpirationTime();
    return NS_OK;
}
Ejemplo n.º 21
0
NS_IMETHODIMP
nsCacheEntryDescriptor::SetExpirationTime(uint32_t expirationTime)
{
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_SETEXPIRATIONTIME));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    mCacheEntry->SetExpirationTime(expirationTime);
    mCacheEntry->MarkEntryDirty();
    return NS_OK;
}
Ejemplo n.º 22
0
NS_IMETHODIMP
nsCacheEntryDescriptor::SetSecurityInfo(nsISupports * securityInfo)
{
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_SETSECURITYINFO));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    mCacheEntry->SetSecurityInfo(securityInfo);
    mCacheEntry->MarkEntryDirty();
    return NS_OK;
}
Ejemplo n.º 23
0
NS_IMETHODIMP
nsCacheEntryDescriptor::VisitMetaData(nsICacheMetaDataVisitor * visitor)
{
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_VISITMETADATA)); 
    // XXX check callers, we're calling out of module
    NS_ENSURE_ARG_POINTER(visitor);
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    return mCacheEntry->VisitMetaDataElements(visitor);
}
Ejemplo n.º 24
0
NS_INTERFACE_MAP_END_THREADSAFE

nsresult nsCacheEntryDescriptor::
nsOutputStreamWrapper::LazyInit()
{
    // Check if we have the descriptor. If not we can't even grab the cache
    // lock since it is not ensured that the cache service still exists.
    if (!mDescriptor)
        return NS_ERROR_NOT_AVAILABLE;

    nsCacheServiceAutoLock lock(LOCK_TELEM(NSOUTPUTSTREAMWRAPPER_LAZYINIT));

    nsCacheAccessMode mode;
    nsresult rv = mDescriptor->GetAccessGranted(&mode);
    if (NS_FAILED(rv)) return rv;

    NS_ENSURE_TRUE(mode & nsICache::ACCESS_WRITE, NS_ERROR_UNEXPECTED);

    nsCacheEntry* cacheEntry = mDescriptor->CacheEntry();
    if (!cacheEntry) return NS_ERROR_NOT_AVAILABLE;

    NS_ASSERTION(mOutput == nullptr, "mOutput set in LazyInit");

    nsCOMPtr<nsIOutputStream> stream;
    rv = nsCacheService::OpenOutputStreamForEntry(cacheEntry, mode, mStartOffset,
                                                  getter_AddRefs(stream));
    if (NS_FAILED(rv))
        return rv;

    nsCacheDevice* device = cacheEntry->CacheDevice();
    if (device) {
        // the entry has been truncated to mStartOffset bytes, inform device
        int32_t size = cacheEntry->DataSize();
        rv = device->OnDataSizeChange(cacheEntry, mStartOffset - size);
        if (NS_SUCCEEDED(rv))
            cacheEntry->SetDataSize(mStartOffset);
    } else {
        rv = NS_ERROR_NOT_AVAILABLE;
    }

    // If anything above failed, clean up internal state and get out of here
    // (see bug #654926)...
    if (NS_FAILED(rv)) {
        nsCacheService::ReleaseObject_Locked(stream.forget().take());
        mDescriptor->mOutputWrapper = nullptr;
        nsCacheService::ReleaseObject_Locked(mDescriptor);
        mDescriptor = nullptr;
        mInitialized = false;
        return rv;
    }

    mOutput = stream;
    mInitialized = true;
    return NS_OK;
}
Ejemplo n.º 25
0
NS_IMETHODIMP
nsCacheEntryDescriptor::GetCacheElement(nsISupports ** result)
{
    NS_ENSURE_ARG_POINTER(result);
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_GETCACHEELEMENT));
    if (!mCacheEntry)                 return NS_ERROR_NOT_AVAILABLE;
    if (mCacheEntry->IsStreamData())  return NS_ERROR_CACHE_DATA_IS_STREAM;

    NS_IF_ADDREF(*result = mCacheEntry->Data());
    return NS_OK;
}
Ejemplo n.º 26
0
NS_IMETHODIMP
nsCacheEntryDescriptor::GetSecurityInfo(nsISupports ** result)
{
    NS_ENSURE_ARG_POINTER(result);
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_GETSECURITYINFO));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    *result = mCacheEntry->SecurityInfo();
    NS_IF_ADDREF(*result);
    return NS_OK;
}
Ejemplo n.º 27
0
NS_IMETHODIMP
nsCacheEntryDescriptor::Close()
{
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_CLOSE));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    // XXX perhaps closing descriptors should clear/sever transports

    // tell nsCacheService we're going away
    nsCacheService::CloseDescriptor(this);
    NS_ASSERTION(mCacheEntry == nullptr, "mCacheEntry not null");

    return NS_OK;
}
Ejemplo n.º 28
0
NS_IMETHODIMP nsCacheEntryDescriptor::GetDataSize(uint32_t *result)
{
    NS_ENSURE_ARG_POINTER(result);
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_GETDATASIZE));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    const char* val = mCacheEntry->GetMetaDataElement("uncompressed-len");
    if (!val) {
        *result = mCacheEntry->DataSize();
    } else {
        *result = atol(val);
    }

    return NS_OK;
}
Ejemplo n.º 29
0
NS_IMETHODIMP
nsCacheEntryDescriptor::SetMetaDataElement(const char *key, const char *value)
{
    NS_ENSURE_ARG_POINTER(key);

    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_SETMETADATAELEMENT));
    NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_NOT_AVAILABLE);

    // XXX allow null value, for clearing key?

    nsresult rv = mCacheEntry->SetMetaDataElement(key, value);
    if (NS_SUCCEEDED(rv))
        mCacheEntry->TouchMetaData();
    return rv;
}
Ejemplo n.º 30
0
nsresult
nsCacheEntryDescriptor::RequestDataSizeChange(int32_t deltaSize)
{
    nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHEENTRYDESCRIPTOR_REQUESTDATASIZECHANGE));
    if (!mCacheEntry)  return NS_ERROR_NOT_AVAILABLE;

    nsresult  rv;
    rv = nsCacheService::OnDataSizeChange(mCacheEntry, deltaSize);
    if (NS_SUCCEEDED(rv)) {
        // XXX review for signed/unsigned math errors
        uint32_t  newDataSize = mCacheEntry->DataSize() + deltaSize;
        mCacheEntry->SetDataSize(newDataSize);
        mCacheEntry->TouchData();
    }
    return rv;
}