void BrowserStreamChild::Deliver() { while (kStreamOpen == mStreamStatus && mPendingData.Length()) { if (DeliverPendingData() && kStreamOpen == mStreamStatus) { SetSuspendedTimer(); return; } } ClearSuspendedTimer(); NS_ASSERTION(kStreamOpen != mStreamStatus || 0 == mPendingData.Length(), "Exit out of the data-delivery loop with pending data"); mPendingData.Clear(); // NPP_StreamAsFile() is documented (at MDN) to be called "when the stream // is complete" -- i.e. after all calls to NPP_WriteReady() and NPP_Write() // have finished. We make these calls asynchronously (from // DeliverPendingData()). So we need to make sure all the "pending data" // has been "delivered" before calling NPP_StreamAsFile() (also // asynchronously). Doing this resolves bug 687610, bug 670036 and possibly // also other bugs. if (mStreamAsFilePending) { if (mStreamStatus == kStreamOpen) mInstance->mPluginIface->asfile(&mInstance->mData, &mStream, mStreamAsFileName.get()); mStreamAsFilePending = false; } if (DESTROY_PENDING == mDestroyPending) { mDestroyPending = DESTROYED; if (mState != DYING) NS_RUNTIMEABORT("mDestroyPending but state not DYING"); NS_ASSERTION(NPRES_DONE != mStreamStatus, "Success status set too early!"); if (kStreamOpen == mStreamStatus) mStreamStatus = NPRES_DONE; (void) mInstance->mPluginIface ->destroystream(&mInstance->mData, &mStream, mStreamStatus); } if (DESTROYED == mDestroyPending && mNotifyPending) { NS_ASSERTION(mStreamNotify, "mDestroyPending but no mStreamNotify?"); mNotifyPending = false; mStreamNotify->NPP_URLNotify(mStreamStatus); delete mStreamNotify; mStreamNotify = NULL; } if (DYING == mState && DESTROYED == mDestroyPending && !mStreamNotify && !mInstanceDying) { SendStreamDestroyed(); mState = DELETING; } }
void BrowserStreamChild::Deliver() { while (kStreamOpen == mStreamStatus && mPendingData.Length()) { if (DeliverPendingData() && kStreamOpen == mStreamStatus) { SetSuspendedTimer(); return; } } ClearSuspendedTimer(); NS_ASSERTION(kStreamOpen != mStreamStatus || 0 == mPendingData.Length(), "Exit out of the data-delivery loop with pending data"); mPendingData.Clear(); if (DESTROY_PENDING == mDestroyPending) { mDestroyPending = DESTROYED; if (mState != DYING) NS_RUNTIMEABORT("mDestroyPending but state not DYING"); NS_ASSERTION(NPRES_DONE != mStreamStatus, "Success status set too early!"); if (kStreamOpen == mStreamStatus) mStreamStatus = NPRES_DONE; (void) mInstance->mPluginIface ->destroystream(&mInstance->mData, &mStream, mStreamStatus); } if (DESTROYED == mDestroyPending && mNotifyPending) { NS_ASSERTION(mStreamNotify, "mDestroyPending but no mStreamNotify?"); mNotifyPending = false; mStreamNotify->NPP_URLNotify(mStreamStatus); delete mStreamNotify; mStreamNotify = NULL; } if (DYING == mState && DESTROYED == mDestroyPending && !mStreamNotify && !mInstanceDying) { SendStreamDestroyed(); mState = DELETING; } }