diff --git a/project/include/Surface.h b/project/include/Surface.h index ea5035cab..1eac69187 100644 --- a/project/include/Surface.h +++ b/project/include/Surface.h @@ -40,7 +40,9 @@ extern bool RpiHardwareDecodeJPeg(I420Callback inCallback, void *inUserData, con struct IAppDataCallback { + virtual void beginCallbacks() = 0; virtual void onAppData(int marker, const uint8 *inBytes,int inLen ) = 0; + virtual void endCallbacks() = 0; }; diff --git a/project/src/common/ExternalInterface.cpp b/project/src/common/ExternalInterface.cpp index 2e7ac4929..1095513d5 100644 --- a/project/src/common/ExternalInterface.cpp +++ b/project/src/common/ExternalInterface.cpp @@ -4136,8 +4136,9 @@ TEXT_PROP_GET_IDX_PRIME(line_offset,LineOffset,int); struct ValueAppDataCallback : public IAppDataCallback { value cbValue; + bool unblocked; - ValueAppDataCallback(value inValue) : cbValue(inValue) { } + ValueAppDataCallback(value inValue) : cbValue(inValue), unblocked(false) { } IAppDataCallback *get() { @@ -4146,13 +4147,31 @@ struct ValueAppDataCallback : public IAppDataCallback return this; } + void beginCallbacks() + { + unblocked = gc_try_unblocking(); + } + void onAppData(int marker, const uint8 *inBytes,int inLen ) { ByteArray byteArray(inLen); uint8 *bytes = byteArray.Bytes(); if (bytes) memcpy(bytes, inBytes, inLen); - val_call2( cbValue, alloc_int(marker), byteArray.mValue ); + try + { + val_call2( cbValue, alloc_int(marker), byteArray.mValue ); + } + catch(...) + { + // Ignore? + } + } + + void endCallbacks() + { + if (unblocked) + gc_enter_blocking(); } }; diff --git a/project/src/common/SurfaceIO.cpp b/project/src/common/SurfaceIO.cpp index f93e72bad..5f048c397 100644 --- a/project/src/common/SurfaceIO.cpp +++ b/project/src/common/SurfaceIO.cpp @@ -270,10 +270,15 @@ static Surface *TryJPEG(FILE *inFile,const uint8 *inData, int inDataLen, IAppDat if (onAppData) { jpeg_saved_marker_ptr marker = cinfo.marker_list; - while(marker) + if (marker) { - onAppData->onAppData(marker->marker, marker->data, marker->data_length); - marker = marker->next; + onAppData->beginCallbacks(); + while(marker) + { + onAppData->onAppData(marker->marker, marker->data, marker->data_length); + marker = marker->next; + } + onAppData->endCallbacks(); } }