This change-bundle fixes memory allocation in streams. Next step is to

make a final pass to make sure we are not leaking memory.  After that, I
want to clean up the build system, and the samples.

M build.xml

- Call make export in mozilla directory

- Fix clean target

M mozilla/Makefile.in

- Added export target
M classes/org/mozilla/pluglet/PlugletLoader.java

- avoid ambiguity by casting

+	    CodeSource codesource = new CodeSource(url,(java.security.cert.Certificate []) null);

M examples/MediaPlayer/JMPlayer.java

- remove debug printfs

M mozilla/npAPInsIInputStreamShim.cpp
M mozilla/npAPInsIInputStreamShim.h

- remove debug printfs

- fix buffer allocation, refactor into its own method.

- Use NPN_Mem* methods for memory allocation.

- isolate lock access to private methods.  Avoids locking when we
  already own the lock, which would cause an assertion.

M mozilla/nppluglet.cpp

- in dtor, check for null mScriptablePeer ivar before accessing it.

M mozilla/nsScriptablePeer.cpp

- whitespace

M src/Pluglet.cpp

- get the plugletEngine from do_GetService().

M src/PlugletEngine.cpp
M src/PlugletFactory.cpp
M src/PlugletLoader.cpp

- remove debug printfs

M test/test.java

- added test finalize.


build.xml classes/org/mozilla/pluglet/PlugletLoader.java examples/MediaPlayer/JMPlayer.java mozilla/Makefile.in mozilla/npAPInsIInputStreamShim.cpp mozilla/npAPInsIInputStreamShim.h mozilla/nppluglet.cpp mozilla/nsScriptablePeer.cpp src/Pluglet.cpp src/PlugletEngine.cpp src/PlugletFactory.cpp src/PlugletLoader.cpp test/test.java


git-svn-id: svn://10.0.0.236/trunk@214609 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
edburns%acm.org
2006-11-02 18:55:50 +00:00
parent c966cb3fa5
commit fbd0e42fb9
13 changed files with 168 additions and 131 deletions

View File

@@ -131,10 +131,24 @@
<exec os="Windows 2000" dir="${basedir}/mozilla" executable="make"
failonerror="yes"/>
<exec os="SunOS" dir="${basedir}/mozilla" failonerror="yes"
executable="gmake">
<arg line="install" />
</exec>
<exec os="Linux" dir="${basedir}/mozilla" failonerror="yes"
executable="make">
<arg line="install" />
</exec>
<exec os="Windows 2000" dir="${basedir}/mozilla" executable="make"
failonerror="yes">
<arg line="install" />
</exec>
</target>
<target name="clean.classes">
<delete dir="${build.home}/org/mozilla/pluglets"/>
<delete dir="${build.home}/org/mozilla/pluglet"/>
</target>
<target name="clean" depends="clean.classes">
@@ -202,20 +216,9 @@
</target>
<target name="compile.examples" depends="compile.classes">
<mkdir dir="build" />
<javac destdir="${basedir}/build"
debug="${compile.debug}"
source="${compile.source}"
deprecation="${compile.deprecation}"
optimize="${compile.optimize}">
<classpath refid="compile.classpath"/>
<src path="${basedir}/examples/MediaPlayer"/>
<include name="*.java"/>
</javac>
<ant inheritall="false" dir="examples/MediaPlayer" />
<ant dir="test" />
</target>

View File

@@ -69,7 +69,7 @@ public class PlugletLoader {
if (policy != Policy.getPolicy()) {
Policy.setPolicy(policy);
}
CodeSource codesource = new CodeSource(url,null);
CodeSource codesource = new CodeSource(url,(java.security.cert.Certificate []) null);
Permission perm = new AllPermission();
PermissionCollection collection = perm.newPermissionCollection();
collection.add(perm);

View File

@@ -23,7 +23,7 @@ public class JMPlayer implements PlugletFactory {
player = new Player();
}
catch (Throwable e) {
System.out.println("debug: edburns: " + e.getMessage());
e.printStackTrace();
}
return player;
}

View File

@@ -92,3 +92,5 @@ LOCAL_INCLUDES = -I./$(XPIDL_GEN_DIR) \
-I$(PLUGIN_SDK)/samples/include \
-I$(PLUGIN_SDK)/../../base/src \
$(NULL)
install::
$(INSTALL) $(IFLAGS1) $(SHARED_LIBRARY) $(DIST)/bin/plugins

View File

@@ -22,46 +22,46 @@
#include "npAPInsIInputStreamShim.h"
#include "nsCRT.h"
#include "npapi.h"
#include "prlog.h"
#include "prlock.h"
#include "nsStreamUtils.h"
const PRUint32 npAPInsIInputStreamShim::INITIAL_BUFFER_LENGTH = 16532;
const PRInt32 npAPInsIInputStreamShim::buffer_increment = 5120;
const uint32 npAPInsIInputStreamShim::INITIAL_BUFFER_LENGTH = 16532;
const uint32 npAPInsIInputStreamShim::buffer_increment = 5120;
const PRInt32 npAPInsIInputStreamShim::do_close_code = -524;
npAPInsIInputStreamShim::npAPInsIInputStreamShim(nsIPluginStreamListener *plugletListener, nsIPluginStreamInfo* streamInfo)
: mPlugletListener(plugletListener),
mStreamInfo(streamInfo),
mBuffer(nsnull), mBufferLength(0), mCountFromPluginHost(0),
mCountFromPluglet(0), mAvailable(0), mAvailableForPluglet(0),
mCountFromPluglet(0), mAvailableForPluglet(0),
mNumWrittenFromPluginHost(0),
mDoClose(PR_FALSE), mDidClose(PR_FALSE), mLock(nsnull),
mDoClose(PR_FALSE), mDidClose(PR_FALSE), mLock(PR_NewLock()),
mHasLock(PR_FALSE),
mCloseStatus(NS_OK), mCallback(nsnull), mCallbackFlags(0)
{
NS_INIT_ISUPPORTS();
mLock = PR_NewLock();
}
npAPInsIInputStreamShim::~npAPInsIInputStreamShim()
{
PR_Lock(mLock);
this->doLock();
DoClose();
mPlugletListener = nsnull;
mStreamInfo = nsnull;
delete [] mBuffer;
NPN_MemFree(mBuffer);
mBuffer = nsnull;
mBufferLength = 0;
PR_Unlock(mLock);
this->doUnlock();
mAvailable = 0;
mAvailableForPluglet = 0;
mNumWrittenFromPluginHost = 0;
mDoClose = PR_TRUE;
@@ -71,6 +71,32 @@ npAPInsIInputStreamShim::~npAPInsIInputStreamShim()
}
PRStatus npAPInsIInputStreamShim::doLock(void)
{
PRStatus result = PR_SUCCESS;
if (!mHasLock) {
PR_ASSERT(mLock);
PR_Lock(mLock);
mHasLock = PR_TRUE;
}
return result;
}
PRStatus npAPInsIInputStreamShim::doUnlock(void)
{
PRStatus result = PR_SUCCESS;
if (mHasLock) {
PR_ASSERT(mLock);
mHasLock = PR_FALSE;
result = PR_Unlock(mLock);
}
return result;
}
//NS_IMPL_ISUPPORTS(npAPInsIInputStreamShim, NS_GET_IID(nsIInputStream))
NS_IMETHODIMP_(nsrefcnt) npAPInsIInputStreamShim::AddRef(void)
{
@@ -109,15 +135,15 @@ npAPInsIInputStreamShim::AllowStreamToReadFromBuffer(int32 len, void* buf,
return rv;
}
PR_Lock(mLock);
this->doLock();
rv = this->CopyFromPluginHostToBuffer(len, buf, outWritten);
PR_Unlock(mLock);
this->doUnlock();
if (NS_SUCCEEDED(rv)) {
rv = mPlugletListener->OnDataAvailable(mStreamInfo, this,
(PRUint32) outWritten);
// rv = mPlugletListener->OnDataAvailable(mStreamInfo, this,
// (PRUint32) outWritten);
}
return rv;
@@ -137,64 +163,23 @@ npAPInsIInputStreamShim::CopyFromPluginHostToBuffer(int32 len, void* buf,
return NS_ERROR_NOT_AVAILABLE;
}
// if we don't have a buffer, create one
if (!mBuffer) {
if (0 < INITIAL_BUFFER_LENGTH) {
mBuffer = new char[INITIAL_BUFFER_LENGTH];
mBufferLength = INITIAL_BUFFER_LENGTH;
}
else {
// make sure we allocate enough buffer to store what is
// currently available.
if (mAvailable < buffer_increment) {
mBufferLength = buffer_increment;
}
else {
PRInt32 bufLengthCalc = mAvailable / buffer_increment;
mBufferLength = buffer_increment +
(bufLengthCalc * buffer_increment);
}
mBuffer = new char[mBufferLength];
}
if (!mBuffer) {
mBufferLength = 0;
return NS_ERROR_FAILURE;
}
}
else {
// See if we need to grow our buffer. If what we have plus what
// we're about to get is greater than the current buffer size...
if (mBufferLength < (mCountFromPluginHost + mAvailable)) {
// create the new buffer
char *tBuffer = new char[mBufferLength + buffer_increment];
if (!tBuffer) {
return NS_ERROR_FAILURE;
}
// copy the old buffer into the new buffer
memcpy(tBuffer, mBuffer, mBufferLength);
// delete the old buffer
delete [] mBuffer;
// update mBuffer;
mBuffer = tBuffer;
// update our bufferLength
mBufferLength += buffer_increment;
}
rv = EnsureBuffer(len);
if (NS_FAILED(rv)) {
return rv;
}
mNumWrittenFromPluginHost = len;
*outWritten = mNumWrittenFromPluginHost;
if (0 < mNumWrittenFromPluginHost) {
// copy the bytes the from the plugin host into our buffer
memcpy(mBuffer + mCountFromPluginHost, buf, mNumWrittenFromPluginHost);
memcpy(((char *) mBuffer) + mCountFromPluginHost, buf,
(size_t) mNumWrittenFromPluginHost);
mCountFromPluginHost += mNumWrittenFromPluginHost;
mAvailableForPluglet = mCountFromPluginHost - mCountFromPluglet;
}
// if we have bytes available for the pluglet, and they it have
// if we have bytes available for the pluglet, and they have
// requested a callback when bytes are available.
if (mCallback && 0 < mAvailableForPluglet
&& !(mCallbackFlags & WAIT_CLOSURE_ONLY)) {
@@ -208,6 +193,48 @@ npAPInsIInputStreamShim::CopyFromPluginHostToBuffer(int32 len, void* buf,
return rv;
}
NS_IMETHODIMP
npAPInsIInputStreamShim::EnsureBuffer(int32 requestedAdditionalLen)
{
// if we don't have a buffer, create one
if (!mBuffer) {
if (0 < INITIAL_BUFFER_LENGTH) {
mBuffer = NPN_MemAlloc(INITIAL_BUFFER_LENGTH);
mBufferLength = INITIAL_BUFFER_LENGTH;
}
if (!mBuffer) {
mBufferLength = 0;
return NS_ERROR_FAILURE;
}
}
else {
// See if we need to grow our buffer. If what we have plus what
// we're about to get is greater than the current buffer size...
int32 additionalLen = requestedAdditionalLen < buffer_increment ?
buffer_increment : requestedAdditionalLen;
if (mBufferLength < (mCountFromPluginHost + additionalLen)) {
// create the new buffer
void *tBuffer = NPN_MemAlloc(mBufferLength + additionalLen);
if (!tBuffer) {
return NS_ERROR_FAILURE;
}
// copy the old buffer into the new buffer
memcpy(tBuffer, mBuffer, mBufferLength);
// delete the old buffer
NPN_MemFree(mBuffer);
// update mBuffer;
mBuffer = tBuffer;
// update our bufferLength
mBufferLength += additionalLen;
}
}
return NS_OK;
}
NS_IMETHODIMP
npAPInsIInputStreamShim::DoClose(void)
@@ -227,9 +254,9 @@ npAPInsIInputStreamShim::DoClose(void)
mCloseStatus = NS_BASE_STREAM_CLOSED;
mDidClose = PR_TRUE;
if (mPlugletListener && mStreamInfo) {
mPlugletListener->OnStopBinding(mStreamInfo, mCloseStatus);
}
// if (mPlugletListener && mStreamInfo) {
// mPlugletListener->OnStopBinding(mStreamInfo, mCloseStatus);
// }
return rv;
}
@@ -254,12 +281,11 @@ npAPInsIInputStreamShim::Available(PRUint32* aResult)
}
return mCloseStatus;
}
PR_ASSERT(mLock);
PR_Lock(mLock);
this->doLock();
*aResult = mAvailableForPluglet;
// *aResult = PR_UINT32_MAX;
rv = NS_OK;
PR_Unlock(mLock);
this->doUnlock();
return rv;
}
@@ -268,12 +294,11 @@ NS_IMETHODIMP
npAPInsIInputStreamShim::Close()
{
nsresult rv = NS_ERROR_FAILURE;
PR_ASSERT(mLock);
PR_Lock(mLock);
this->doLock();
mDoClose = PR_TRUE;
mCloseStatus = NS_BASE_STREAM_CLOSED;
rv = NS_OK;
PR_Unlock(mLock);
this->doUnlock();
return rv;
}
@@ -291,21 +316,21 @@ npAPInsIInputStreamShim::Read(char* aBuffer, PRUint32 aCount, PRUint32 *aNumRead
}
*aNumRead = 0;
PR_ASSERT(mLock);
PR_ASSERT(mCountFromPluglet <= mCountFromPluginHost);
PR_Lock(mLock);
this->doLock();
if (mAvailableForPluglet) {
if (aCount <= (mCountFromPluginHost - mCountFromPluglet)) {
// what she's asking for is less than or equal to what we have
memcpy(aBuffer, (mBuffer + mCountFromPluglet), aCount);
memcpy(aBuffer, (((char *)mBuffer) + mCountFromPluglet), aCount);
mCountFromPluglet += aCount;
*aNumRead = aCount;
}
else {
// what she's asking for is more than what we have
memcpy(aBuffer, (mBuffer + mCountFromPluglet),
memcpy(aBuffer, ((char *)mBuffer) + mCountFromPluglet,
(mCountFromPluginHost - mCountFromPluglet));
*aNumRead = (mCountFromPluginHost - mCountFromPluglet);
@@ -318,7 +343,7 @@ npAPInsIInputStreamShim::Read(char* aBuffer, PRUint32 aCount, PRUint32 *aNumRead
rv = NS_BASE_STREAM_WOULD_BLOCK;
}
PR_Unlock(mLock);
this->doUnlock();
return rv;
}
@@ -335,10 +360,9 @@ npAPInsIInputStreamShim::ReadSegments(nsWriteSegmentFun writer, void * aClosure,
return mCloseStatus;
}
*aNumRead = 0;
PR_ASSERT(mLock);
PR_ASSERT(mCountFromPluglet <= mCountFromPluginHost);
PR_Lock(mLock);
this->doLock();
PRInt32 bytesToWrite = mAvailableForPluglet;
PRUint32 bytesWritten;
@@ -355,7 +379,7 @@ npAPInsIInputStreamShim::ReadSegments(nsWriteSegmentFun writer, void * aClosure,
while (bytesToWrite) {
// what she's asking for is less than or equal to what we have
rv = writer(this, aClosure,
(mBuffer + mCountFromPluglet),
(((char *)mBuffer) + mCountFromPluglet),
totalBytesWritten, bytesToWrite, &bytesWritten);
if (NS_FAILED(rv)) {
break;
@@ -369,7 +393,7 @@ npAPInsIInputStreamShim::ReadSegments(nsWriteSegmentFun writer, void * aClosure,
*aNumRead = totalBytesWritten;
mAvailableForPluglet -= totalBytesWritten;
PR_Unlock(mLock);
this->doUnlock();
}
NS_IMETHODIMP
@@ -396,7 +420,7 @@ npAPInsIInputStreamShim::AsyncWait(nsIInputStreamCallback *aCallback,
PRUint32 aFlags, PRUint32 aRequestedCount,
nsIEventTarget *aEventTarget)
{
PR_Lock(mLock);
this->doLock();
mCallback = nsnull;
mCallbackFlags = nsnull;
@@ -419,7 +443,7 @@ npAPInsIInputStreamShim::AsyncWait(nsIInputStreamCallback *aCallback,
mCallbackFlags = aFlags;
}
PR_Unlock(mLock);
this->doUnlock();
return NS_OK;
}

View File

@@ -56,6 +56,8 @@ private:
NS_IMETHOD CopyFromPluginHostToBuffer(int32 len, void* buf,
int32* outWritten);
NS_IMETHOD EnsureBuffer(int32 len);
nsCOMPtr<nsIPluginStreamListener> mPlugletListener;
nsCOMPtr<nsIPluginStreamInfo> mStreamInfo;
@@ -72,7 +74,7 @@ private:
*/
char *mBuffer;
void *mBuffer;
/**
@@ -80,7 +82,7 @@ private:
*/
PRUint32 mBufferLength;
uint32 mBufferLength;
/**
@@ -90,7 +92,7 @@ private:
*/
PRUint32 mCountFromPluginHost;
uint32 mCountFromPluginHost;
/**
@@ -98,7 +100,7 @@ private:
*/
PRUint32 mCountFromPluglet;
uint32 mCountFromPluglet;
/**
@@ -106,7 +108,7 @@ private:
*/
PRInt32 mAvailable;
uint32 mAvailable;
/**
@@ -115,7 +117,7 @@ private:
*/
PRInt32 mAvailableForPluglet;
uint32 mAvailableForPluglet;
/**
@@ -124,7 +126,7 @@ private:
*/
PRInt32 mNumWrittenFromPluginHost;
uint32 mNumWrittenFromPluginHost;
PRBool mDoClose;
@@ -137,6 +139,9 @@ private:
*/
PRLock *mLock;
PRStatus doLock(void);
PRStatus doUnlock(void);
PRBool mHasLock;
nsresult mCloseStatus;
@@ -144,8 +149,8 @@ private:
PRUint32 mCallbackFlags;
static const PRUint32 INITIAL_BUFFER_LENGTH;
static const PRInt32 buffer_increment;
static const uint32 INITIAL_BUFFER_LENGTH;
static const uint32 buffer_increment;
static const PRInt32 do_close_code;

View File

@@ -105,7 +105,6 @@ NPError NS_PluginInitialize()
// in the future so we don't need to do casting of any sort.
if(sm) {
sm->QueryInterface(NS_GET_IID(nsIServiceManager), (void**)&gServiceManager);
printf("debug: edburns: gServiceManager: %p\n\n", gServiceManager);
NS_RELEASE(sm);
}
@@ -183,15 +182,20 @@ nsPluginInstance::~nsPluginInstance()
if (mPluglet) {
mPluglet->Destroy();
mPluglet = nsnull;
}
mInitialized = PR_FALSE;
// mScriptablePeer may be also held by the browser
// so releasing it here does not guarantee that it is over
// we should take precaution in case it will be called later
// and zero its mPlugin member
mScriptablePeer->SetInstance(nsnull);
NS_IF_RELEASE(mScriptablePeer);
if (mScriptablePeer) {
// mScriptablePeer may be also held by the browser
// so releasing it here does not guarantee that it is over
// we should take precaution in case it will be called later
// and zero its mPlugin member
mScriptablePeer->SetInstance(nsnull);
NS_IF_RELEASE(mScriptablePeer);
}
}
NPBool nsPluginInstance::init(NPWindow* aWindow)
@@ -330,9 +334,6 @@ int32 nsPluginInstance::Write(NPStream *stream, int32 offset,
nsresult rv = NS_ERROR_NULL_POINTER;
rv = shim->AllowStreamToReadFromBuffer(len, buffer, &result);
if (NS_SUCCEEDED(rv)) {
printf("debug: edburns: passed %d bytes to pluglet\n", result);
}
return result;
}

View File

@@ -109,7 +109,7 @@ NS_IMETHODIMP nsScriptablePeer::QueryInterface(const nsIID& aIID, void** aInstan
void nsScriptablePeer::SetInstance(nsPluginInstance* plugin)
{
mPlugin = plugin;
mPlugin = plugin;
}
//

View File

@@ -74,14 +74,20 @@ Pluglet::~Pluglet() {
Registry::Remove(jthis);
JNIEnv *jniEnv = nsnull;
nsresult rv;
rv = plugletEngine->GetJNIEnv(&jniEnv);
if (NS_FAILED(rv)) {
PR_LOG(PlugletLog::log, PR_LOG_DEBUG,
("Pluglet::~Pluglet: plugletEngine->GetJNIEnv failed\n"));
return;
plugletEngine = do_GetService(PLUGLETENGINE_ContractID, &rv);
if (plugletEngine) {
rv = plugletEngine->GetJNIEnv(&jniEnv);
if (NS_FAILED(rv)) {
PR_LOG(PlugletLog::log, PR_LOG_DEBUG,
("Pluglet::~Pluglet: plugletEngine->GetJNIEnv failed\n"));
return;
}
jniEnv->DeleteGlobalRef(jthis);
if (jniEnv->ExceptionOccurred()) {
jniEnv->ExceptionDescribe();
}
}
jniEnv->DeleteGlobalRef(jthis);
peer = nsnull;
}

View File

@@ -369,8 +369,6 @@ iPlugletEngine::GetInstance(void ** result)
NS_GET_IID(iPlugletEngine),
(void **) &result);
printf("debug: edburns: plugletEngine instance rv: %d\n", rv);
printf("debug: edburns: plugletEngine instance result: %p\n", *result);
if (NS_FAILED(rv)) {
PR_LOG(PlugletLog::log, PR_LOG_DEBUG,
("Pluglet::PlugletFactory: Cannot access iPlugletEngine service\n"));

View File

@@ -164,13 +164,11 @@ PlugletFactory::PlugletFactory(const char *mimeDescription, const char *path) :
nsresult rv = NS_ERROR_FAILURE;
plugletEngine = do_GetService(PLUGLETENGINE_ContractID, &rv);
printf("debug: edburns: PlugletFactory ctor: rv: %d\n", rv);
if (NS_FAILED(rv)) {
PR_LOG(PlugletLog::log, PR_LOG_DEBUG,
("Pluglet::PlugletFactory: Cannot access iPlugletEngine service\n"));
return;
}
printf("debug: edburns: PlugletFactory ctor: this: %p\n", this);
}
PlugletFactory::~PlugletFactory(void) {

View File

@@ -55,9 +55,6 @@ NS_EXPORT void PlugletLoader::Initialize(void) {
nsCOMPtr<iPlugletEngine> plugletEngine =
do_GetService(PLUGLETENGINE_ContractID, &rv);
printf("debug: edburns: plugletEngine: %p", plugletEngine.get());
if (NS_FAILED(rv)) {
return;
}
@@ -144,7 +141,6 @@ char * PlugletLoader::GetMIMEDescription(const char * path) {
const char* str = env->GetStringUTFChars(mimeDescription,nsnull);
printf("debug: edburns: mime description: %s\n", str);
char *res = nsnull;
if(str) {
res = new char[strlen(str)+1];

View File

@@ -171,6 +171,10 @@ class TestInstance implements Pluglet {
*/
public void print(PrinterJob printerJob) {
}
protected void finalize() {
org.mozilla.util.DebugPluglet.print("--TestInstance.finalize()\n");
}
}
class TestStreamListener implements PlugletStreamListener {