flatlaf-natives-windows: fixed memory allocation error handling (issue #591)

This commit is contained in:
Karl Tauber
2022-11-26 19:14:24 +01:00
4 changed files with 50 additions and 12 deletions

View File

@@ -99,8 +99,11 @@ HWND FlatWndProc::install( JNIEnv *env, jobject obj, jobject window ) {
return 0; return 0;
// create HWND map // create HWND map
if( hwndMap == NULL ) if( hwndMap == NULL ) {
hwndMap = new HWNDMap(); hwndMap = new HWNDMap();
if( hwndMap == NULL )
return 0;
}
// get window handle // get window handle
HWND hwnd = getWindowHandle( env, window ); HWND hwnd = getWindowHandle( env, window );
@@ -108,10 +111,17 @@ HWND FlatWndProc::install( JNIEnv *env, jobject obj, jobject window ) {
return 0; return 0;
FlatWndProc* fwp = new FlatWndProc(); FlatWndProc* fwp = new FlatWndProc();
if( fwp == NULL )
return 0;
if( !hwndMap->put( hwnd, fwp ) ) {
delete fwp;
return 0;
}
env->GetJavaVM( &fwp->jvm ); env->GetJavaVM( &fwp->jvm );
fwp->obj = env->NewGlobalRef( obj ); fwp->obj = env->NewGlobalRef( obj );
fwp->hwnd = hwnd; fwp->hwnd = hwnd;
hwndMap->put( hwnd, fwp );
// replace window procedure // replace window procedure
fwp->defaultWndProc = reinterpret_cast<WNDPROC>( fwp->defaultWndProc = reinterpret_cast<WNDPROC>(

View File

@@ -43,8 +43,8 @@ public:
HWNDMap::HWNDMap() { HWNDMap::HWNDMap() {
size = 0; size = 0;
capacity = DEFAULT_CAPACITY; capacity = 0;
table = new Entry[capacity]; table = NULL;
::InitializeCriticalSection( &criticalSection ); ::InitializeCriticalSection( &criticalSection );
@@ -58,7 +58,7 @@ LPVOID HWNDMap::get( HWND key ) {
return (index >= 0) ? table[index].value : NULL; return (index >= 0) ? table[index].value : NULL;
} }
void HWNDMap::put( HWND key, LPVOID value ) { bool HWNDMap::put( HWND key, LPVOID value ) {
LOCK lock( &criticalSection ); LOCK lock( &criticalSection );
int index = binarySearch( key ); int index = binarySearch( key );
@@ -68,9 +68,10 @@ void HWNDMap::put( HWND key, LPVOID value ) {
table[index].value = value; table[index].value = value;
} else { } else {
// insert new key // insert new key
ensureCapacity( size + 1 ); if( !ensureCapacity() )
return false;
// make roor for new entry // make room for new entry
index = -(index + 1); index = -(index + 1);
for( int i = size - 1; i >= index; i-- ) for( int i = size - 1; i >= index; i-- )
table[i + 1] = table[i]; table[i + 1] = table[i];
@@ -82,6 +83,7 @@ void HWNDMap::put( HWND key, LPVOID value ) {
} }
// dump( "put" ); // dump( "put" );
return true;
} }
void HWNDMap::remove( HWND key ) { void HWNDMap::remove( HWND key ) {
@@ -102,6 +104,9 @@ void HWNDMap::remove( HWND key ) {
} }
int HWNDMap::binarySearch( HWND key ) { int HWNDMap::binarySearch( HWND key ) {
if( table == NULL )
return -1;
__int64 ikey = reinterpret_cast<__int64>( key ); __int64 ikey = reinterpret_cast<__int64>( key );
int low = 0; int low = 0;
int high = size - 1; int high = size - 1;
@@ -121,23 +126,37 @@ int HWNDMap::binarySearch( HWND key ) {
return -(low + 1); return -(low + 1);
} }
void HWNDMap::ensureCapacity( int minCapacity ) { bool HWNDMap::ensureCapacity() {
if( table == NULL ) {
table = new Entry[DEFAULT_CAPACITY];
if( table == NULL )
return false;
capacity = DEFAULT_CAPACITY;
return true;
}
// check capacity
int minCapacity = size + 1;
if( minCapacity <= capacity ) if( minCapacity <= capacity )
return; return true;
// allocate new table // allocate new table
int newCapacity = minCapacity + INCREASE_CAPACITY; int newCapacity = minCapacity + INCREASE_CAPACITY;
Entry* newTable = new Entry[newCapacity]; Entry* newTable = new Entry[newCapacity];
if( newTable == NULL )
return false;
// copy old table to new table // copy old table to new table
for( int i = 0; i < capacity; i++ ) for( int i = 0; i < capacity; i++ )
newTable[i] = table[i]; newTable[i] = table[i];
// delete old table // delete old table
delete table; delete[] table;
table = newTable; table = newTable;
capacity = newCapacity; capacity = newCapacity;
return true;
} }
/* /*

View File

@@ -42,12 +42,12 @@ public:
HWNDMap(); HWNDMap();
LPVOID get( HWND key ); LPVOID get( HWND key );
void put( HWND key, LPVOID value ); bool put( HWND key, LPVOID value );
void remove( HWND key ); void remove( HWND key );
private: private:
int binarySearch( HWND key ); int binarySearch( HWND key );
void ensureCapacity( int newCapacity ); bool ensureCapacity();
// void dump( char* msg ); // void dump( char* msg );
}; };

View File

@@ -42,14 +42,23 @@ BOOL WINAPI _DllMainCRTStartup( HINSTANCE instance, DWORD reason, LPVOID reserve
} }
void* __cdecl operator new( size_t cb ) { void* __cdecl operator new( size_t cb ) {
// printf( "new %d\n", cb );
return ::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, cb ); return ::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, cb );
} }
void* __cdecl operator new[]( size_t cb ) { void* __cdecl operator new[]( size_t cb ) {
// printf( "new[] %d\n", cb );
return ::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, cb ); return ::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, cb );
} }
void __cdecl operator delete( void* pv, size_t cb ) { void __cdecl operator delete( void* pv, size_t cb ) {
// printf( "delete %p %d\n", pv, cb );
if( pv != NULL )
::HeapFree( ::GetProcessHeap(), 0, pv );
}
void __cdecl operator delete[]( void* pv ) {
// printf( "delete[] %p\n", pv );
if( pv != NULL ) if( pv != NULL )
::HeapFree( ::GetProcessHeap(), 0, pv ); ::HeapFree( ::GetProcessHeap(), 0, pv );
} }