xfreerdp: fix multiple egfx-related memory leaks
This commit is contained in:
parent
cd65a0d6b8
commit
78d3c82798
@ -475,7 +475,7 @@ int dvcman_receive_channel_data_first(IWTSVirtualChannelManager* pChannelMgr, UI
|
||||
|
||||
int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId, wStream* data)
|
||||
{
|
||||
int error = 0;
|
||||
int status = 0;
|
||||
DVCMAN_CHANNEL* channel;
|
||||
UINT32 dataSize = Stream_GetRemainingLength(data);
|
||||
|
||||
@ -504,16 +504,16 @@ int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, UINT32 C
|
||||
{
|
||||
Stream_SealLength(channel->dvc_data);
|
||||
Stream_SetPosition(channel->dvc_data, 0);
|
||||
error = channel->channel_callback->OnDataReceived(channel->channel_callback, channel->dvc_data);
|
||||
status = channel->channel_callback->OnDataReceived(channel->channel_callback, channel->dvc_data);
|
||||
Stream_Release(channel->dvc_data);
|
||||
channel->dvc_data = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error = channel->channel_callback->OnDataReceived(channel->channel_callback, data);
|
||||
status = channel->channel_callback->OnDataReceived(channel->channel_callback, data);
|
||||
}
|
||||
|
||||
return error;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -210,6 +210,8 @@ int rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s
|
||||
context->ResetGraphics(context, &pdu);
|
||||
}
|
||||
|
||||
free(pdu.monitorDefArray);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -595,6 +597,8 @@ int rdpgfx_recv_cache_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream*
|
||||
context->CacheToSurface(context, &pdu);
|
||||
}
|
||||
|
||||
free(pdu.destPts);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -850,7 +854,11 @@ static int rdpgfx_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManag
|
||||
|
||||
static int rdpgfx_plugin_terminated(IWTSPlugin* pPlugin)
|
||||
{
|
||||
int count;
|
||||
int index;
|
||||
ULONG_PTR* pKeys = NULL;
|
||||
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) pPlugin;
|
||||
RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
|
||||
|
||||
WLog_Print(gfx->log, WLOG_DEBUG, "Terminated");
|
||||
|
||||
@ -859,8 +867,41 @@ static int rdpgfx_plugin_terminated(IWTSPlugin* pPlugin)
|
||||
|
||||
zgfx_context_free(gfx->zgfx);
|
||||
|
||||
count = HashTable_GetKeys(gfx->SurfaceTable, &pKeys);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
RDPGFX_DELETE_SURFACE_PDU pdu;
|
||||
|
||||
pdu.surfaceId = ((UINT16) pKeys[index]) - 1;
|
||||
|
||||
if (context && context->DeleteSurface)
|
||||
{
|
||||
context->DeleteSurface(context, &pdu);
|
||||
}
|
||||
}
|
||||
|
||||
free(pKeys);
|
||||
|
||||
HashTable_Free(gfx->SurfaceTable);
|
||||
|
||||
for (index = 0; index < gfx->MaxCacheSlot; index++)
|
||||
{
|
||||
if (gfx->CacheSlots[index])
|
||||
{
|
||||
RDPGFX_EVICT_CACHE_ENTRY_PDU pdu;
|
||||
|
||||
pdu.cacheSlot = (UINT16) index;
|
||||
|
||||
if (context && context->EvictCacheEntry)
|
||||
{
|
||||
context->EvictCacheEntry(context, &pdu);
|
||||
}
|
||||
|
||||
gfx->CacheSlots[index] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
free(gfx);
|
||||
|
||||
return 0;
|
||||
|
@ -38,11 +38,20 @@ void xf_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEven
|
||||
}
|
||||
else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
|
||||
{
|
||||
xf_register_graphics_pipeline(xfc, (RdpgfxClientContext*) e->pInterface);
|
||||
xf_graphics_pipeline_init(xfc, (RdpgfxClientContext*) e->pInterface);
|
||||
}
|
||||
}
|
||||
|
||||
void xf_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e)
|
||||
{
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0)
|
||||
{
|
||||
xfc->rdpei = NULL;
|
||||
}
|
||||
else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
|
||||
{
|
||||
xf_graphics_pipeline_uninit(xfc, (RdpgfxClientContext*) e->pInterface);
|
||||
}
|
||||
}
|
||||
|
@ -610,7 +610,7 @@ int xf_EvictCacheEntry(RdpgfxClientContext* context, RDPGFX_EVICT_CACHE_ENTRY_PD
|
||||
{
|
||||
xfGfxCacheEntry* cacheEntry;
|
||||
|
||||
printf("xf_EvictCacheEntry\n");
|
||||
//printf("xf_EvictCacheEntry\n");
|
||||
|
||||
cacheEntry = (xfGfxCacheEntry*) context->GetCacheSlotData(context, evictCacheEntry->cacheSlot);
|
||||
|
||||
@ -639,7 +639,7 @@ int xf_MapSurfaceToWindow(RdpgfxClientContext* context, RDPGFX_MAP_SURFACE_TO_WI
|
||||
return 1;
|
||||
}
|
||||
|
||||
void xf_register_graphics_pipeline(xfContext* xfc, RdpgfxClientContext* gfx)
|
||||
void xf_graphics_pipeline_init(xfContext* xfc, RdpgfxClientContext* gfx)
|
||||
{
|
||||
xfc->gfx = gfx;
|
||||
gfx->custom = (void*) xfc;
|
||||
@ -662,3 +662,11 @@ void xf_register_graphics_pipeline(xfContext* xfc, RdpgfxClientContext* gfx)
|
||||
|
||||
region16_init(&(xfc->invalidRegion));
|
||||
}
|
||||
|
||||
void xf_graphics_pipeline_uninit(xfContext* xfc, RdpgfxClientContext* gfx)
|
||||
{
|
||||
region16_uninit(&(xfc->invalidRegion));
|
||||
|
||||
gfx->custom = NULL;
|
||||
xfc->gfx = NULL;
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ typedef struct xf_gfx_cache_entry xfGfxCacheEntry;
|
||||
|
||||
int xf_OutputExpose(xfContext* xfc, int x, int y, int width, int height);
|
||||
|
||||
void xf_register_graphics_pipeline(xfContext* xfc, RdpgfxClientContext* gfx);
|
||||
void xf_graphics_pipeline_init(xfContext* xfc, RdpgfxClientContext* gfx);
|
||||
void xf_graphics_pipeline_uninit(xfContext* xfc, RdpgfxClientContext* gfx);
|
||||
|
||||
#endif /* __XF_GRAPHICS_PIPELINE_H */
|
||||
|
@ -822,25 +822,33 @@ BOOL xf_IsWindowBorder(xfContext *xfc, xfWindow *xfw, int x, int y)
|
||||
|
||||
void xf_DestroyWindow(xfContext *xfc, xfWindow *window)
|
||||
{
|
||||
if(window == NULL)
|
||||
if (!window)
|
||||
return;
|
||||
if(xfc->window == window)
|
||||
|
||||
if (xfc->window == window)
|
||||
xfc->window = NULL;
|
||||
if(window->gc)
|
||||
|
||||
if (window->gc)
|
||||
XFreeGC(xfc->display, window->gc);
|
||||
if(window->handle)
|
||||
|
||||
if (window->handle)
|
||||
{
|
||||
XUnmapWindow(xfc->display, window->handle);
|
||||
XDestroyWindow(xfc->display, window->handle);
|
||||
}
|
||||
free(window);
|
||||
if(window->xfwin)
|
||||
|
||||
if (window->xfwin)
|
||||
munmap(0, sizeof(*window->xfwin));
|
||||
if(window->shmid >= 0)
|
||||
|
||||
if (window->shmid >= 0)
|
||||
close(window->shmid);
|
||||
|
||||
shm_unlink(get_shm_id());
|
||||
|
||||
window->xfwin = -1;
|
||||
window->shmid = -1;
|
||||
|
||||
free(window);
|
||||
}
|
||||
|
||||
rdpWindow *xf_rdpWindowFromWindow(xfContext *xfc, Window wnd)
|
||||
|
@ -517,11 +517,16 @@ out_free:
|
||||
|
||||
void freerdp_dynamic_channel_collection_free(rdpSettings* settings)
|
||||
{
|
||||
UINT32 index;
|
||||
int j;
|
||||
UINT32 i;
|
||||
|
||||
for (index = 0; index < settings->DynamicChannelCount; index++)
|
||||
for (i = 0; i < settings->DynamicChannelCount; i++)
|
||||
{
|
||||
free(settings->DynamicChannelArray[index]);
|
||||
for (j = 0; j < settings->DynamicChannelArray[i]->argc; j++)
|
||||
free(settings->DynamicChannelArray[i]->argv[j]);
|
||||
|
||||
free(settings->DynamicChannelArray[i]->argv);
|
||||
free(settings->DynamicChannelArray[i]);
|
||||
}
|
||||
|
||||
free(settings->DynamicChannelArray);
|
||||
|
@ -179,6 +179,7 @@ static void* svc_plugin_thread_func(void* arg)
|
||||
IFCALL(plugin->connect_callback, plugin);
|
||||
|
||||
SetEvent(plugin->started);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (!MessageQueue_Wait(plugin->MsgPipe->In))
|
||||
@ -238,7 +239,12 @@ static void svc_plugin_process_terminated(rdpSvcPlugin* plugin)
|
||||
|
||||
MessagePipe_Free(plugin->MsgPipe);
|
||||
CloseHandle(plugin->thread);
|
||||
CloseHandle(plugin->started);
|
||||
|
||||
if (plugin->started)
|
||||
{
|
||||
CloseHandle(plugin->started);
|
||||
plugin->started = NULL;
|
||||
}
|
||||
|
||||
plugin->channel_entry_points.pVirtualChannelClose(plugin->OpenHandle);
|
||||
|
||||
@ -248,10 +254,10 @@ static void svc_plugin_process_terminated(rdpSvcPlugin* plugin)
|
||||
plugin->data_in = NULL;
|
||||
}
|
||||
|
||||
IFCALL(plugin->terminate_callback, plugin);
|
||||
|
||||
svc_plugin_remove_open_handle_data(plugin->OpenHandle);
|
||||
svc_plugin_remove_init_handle_data(plugin->InitHandle);
|
||||
|
||||
IFCALL(plugin->terminate_callback, plugin);
|
||||
}
|
||||
|
||||
static VOID VCAPITYPE svc_plugin_init_event(LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength)
|
||||
@ -297,7 +303,7 @@ void svc_plugin_init(rdpSvcPlugin* plugin, CHANNEL_ENTRY_POINTS* pEntryPoints)
|
||||
|
||||
plugin->channel_entry_points.pInterface = *(plugin->channel_entry_points.ppInterface);
|
||||
plugin->channel_entry_points.ppInterface = &(plugin->channel_entry_points.pInterface);
|
||||
plugin->started = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||
plugin->started = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
plugin->pool = StreamPool_New(TRUE, 10);
|
||||
|
||||
svc_plugin_add_init_handle_data(plugin->InitHandle, plugin);
|
||||
@ -305,8 +311,17 @@ void svc_plugin_init(rdpSvcPlugin* plugin, CHANNEL_ENTRY_POINTS* pEntryPoints)
|
||||
|
||||
void svc_plugin_terminate(rdpSvcPlugin* plugin)
|
||||
{
|
||||
StreamPool_Free(plugin->pool);
|
||||
CloseHandle(plugin->started);
|
||||
if (plugin->pool)
|
||||
{
|
||||
StreamPool_Free(plugin->pool);
|
||||
plugin->pool = NULL;
|
||||
}
|
||||
|
||||
if (plugin->started)
|
||||
{
|
||||
CloseHandle(plugin->started);
|
||||
plugin->started = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int svc_plugin_send(rdpSvcPlugin* plugin, wStream* data_out)
|
||||
|
@ -326,6 +326,8 @@ WINPR_API void CountdownEvent_Free(wCountdownEvent* countdown);
|
||||
|
||||
/* Hash Table */
|
||||
|
||||
typedef void (*KEY_VALUE_FREE_FN)(void* context, void* key, void* value);
|
||||
|
||||
struct _wHashTable
|
||||
{
|
||||
BOOL synchronized;
|
||||
@ -342,6 +344,9 @@ struct _wHashTable
|
||||
unsigned long (*hashFunction)(void* key);
|
||||
void (*keyDeallocator)(void* key);
|
||||
void (*valueDeallocator)(void* value);
|
||||
|
||||
void* context;
|
||||
KEY_VALUE_FREE_FN pfnKeyValueFree;
|
||||
};
|
||||
typedef struct _wHashTable wHashTable;
|
||||
|
||||
@ -354,6 +359,8 @@ WINPR_API BOOL HashTable_ContainsKey(wHashTable* table, void* key);
|
||||
WINPR_API BOOL HashTable_ContainsValue(wHashTable* table, void* value);
|
||||
WINPR_API void* HashTable_GetItemValue(wHashTable* table, void* key);
|
||||
WINPR_API BOOL HashTable_SetItemValue(wHashTable* table, void* key, void* value);
|
||||
WINPR_API void HashTable_SetFreeFunction(wHashTable* table, void* context, KEY_VALUE_FREE_FN pfnKeyValueFree);
|
||||
WINPR_API int HashTable_GetKeys(wHashTable* table, ULONG_PTR** ppKeys);
|
||||
|
||||
WINPR_API wHashTable* HashTable_New(BOOL synchronized);
|
||||
WINPR_API void HashTable_Free(wHashTable* table);
|
||||
|
@ -368,6 +368,9 @@ void HashTable_Clear(wHashTable* table)
|
||||
{
|
||||
nextPair = pair->next;
|
||||
|
||||
if (table->pfnKeyValueFree)
|
||||
table->pfnKeyValueFree(table->context, pair->key, pair->value);
|
||||
|
||||
if (table->keyDeallocator)
|
||||
table->keyDeallocator((void*) pair->key);
|
||||
|
||||
@ -389,6 +392,48 @@ void HashTable_Clear(wHashTable* table)
|
||||
LeaveCriticalSection(&table->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of keys as an array
|
||||
*/
|
||||
|
||||
int HashTable_GetKeys(wHashTable* table, ULONG_PTR** ppKeys)
|
||||
{
|
||||
int iKey;
|
||||
int count;
|
||||
int index;
|
||||
ULONG_PTR* pKeys;
|
||||
wKeyValuePair* pair;
|
||||
wKeyValuePair* nextPair;
|
||||
|
||||
if (table->synchronized)
|
||||
EnterCriticalSection(&table->lock);
|
||||
|
||||
iKey = 0;
|
||||
count = table->numOfElements;
|
||||
pKeys = (ULONG_PTR*) calloc(count, sizeof(ULONG_PTR));
|
||||
|
||||
for (index = 0; index < table->numOfBuckets; index++)
|
||||
{
|
||||
pair = table->bucketArray[index];
|
||||
|
||||
while (pair)
|
||||
{
|
||||
nextPair = pair->next;
|
||||
|
||||
pKeys[iKey++] = (ULONG_PTR) pair->key;
|
||||
|
||||
pair = nextPair;
|
||||
}
|
||||
}
|
||||
|
||||
if (table->synchronized)
|
||||
LeaveCriticalSection(&table->lock);
|
||||
|
||||
*ppKeys = pKeys;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the HashTable contains a specific key.
|
||||
*/
|
||||
@ -465,6 +510,12 @@ BOOL HashTable_ContainsValue(wHashTable* table, void* value)
|
||||
return status;
|
||||
}
|
||||
|
||||
void HashTable_SetFreeFunction(wHashTable* table, void* context, KEY_VALUE_FREE_FN pfnKeyValueFree)
|
||||
{
|
||||
table->context = context;
|
||||
table->pfnKeyValueFree = pfnKeyValueFree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construction, Destruction
|
||||
*/
|
||||
|
@ -144,8 +144,7 @@ int ListDictionary_GetKeys(wListDictionary* listDictionary, ULONG_PTR** ppKeys)
|
||||
}
|
||||
}
|
||||
|
||||
pKeys = (ULONG_PTR*) malloc(sizeof(ULONG_PTR) * count);
|
||||
ZeroMemory(pKeys, sizeof(ULONG_PTR) * count);
|
||||
pKeys = (ULONG_PTR*) calloc(count, sizeof(ULONG_PTR));
|
||||
|
||||
index = 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user