Module: wine Branch: master Commit: 4a3054e445e86472a3e4b5d12a2718708c863df0 URL: http://source.winehq.org/git/wine.git/?a=commit;h=4a3054e445e86472a3e4b5d12a...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Tue Nov 15 20:26:47 2016 +0300
oledb32: Use growing array to store error records.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/oledb32/errorinfo.c | 65 ++++++++++++++++++++++++++++---------------- dlls/oledb32/oledb_private.h | 5 ++++ 2 files changed, 47 insertions(+), 23 deletions(-)
diff --git a/dlls/oledb32/errorinfo.c b/dlls/oledb32/errorinfo.c index 4a56b46..0875d82 100644 --- a/dlls/oledb32/errorinfo.c +++ b/dlls/oledb32/errorinfo.c @@ -40,7 +40,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(oledb);
struct ErrorEntry { - struct list entry; ERRORINFO info; DISPPARAMS dispparams; IUnknown *unknown; @@ -53,7 +52,9 @@ typedef struct ErrorInfoImpl IErrorRecords IErrorRecords_iface; LONG ref;
- struct list errors; + struct ErrorEntry *records; + unsigned int allocated; + unsigned int count; } ErrorInfoImpl;
static inline ErrorInfoImpl *impl_from_IErrorInfo( IErrorInfo *iface ) @@ -103,20 +104,19 @@ static ULONG WINAPI IErrorInfoImpl_Release(IErrorInfo* iface) { ErrorInfoImpl *This = impl_from_IErrorInfo(iface); ULONG ref = InterlockedDecrement(&This->ref); - struct ErrorEntry *cursor, *cursor2;
TRACE("(%p)->%u\n",This,ref+1);
if (!ref) { - LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->errors, struct ErrorEntry, entry) - { - list_remove(&cursor->entry); - if(cursor->unknown) - IUnknown_Release(cursor->unknown); + unsigned int i;
- heap_free(cursor); + for (i = 0; i < This->count; i++) + { + if (This->records[i].unknown) + IUnknown_Release(This->records[i].unknown); } + heap_free(This->records); heap_free(This); } return ref; @@ -233,10 +233,27 @@ static HRESULT WINAPI errorrec_AddErrorRecord(IErrorRecords *iface, ERRORINFO *p if(!pErrorInfo) return E_INVALIDARG;
- entry = heap_alloc(sizeof(*entry)); - if(!entry) - return E_OUTOFMEMORY; + if (!This->records) + { + const unsigned int initial_size = 16; + if (!(This->records = heap_alloc(initial_size * sizeof(*This->records)))) + return E_OUTOFMEMORY; + + This->allocated = initial_size; + } + else if (This->count == This->allocated) + { + struct ErrorEntry *new_ptr; + + new_ptr = heap_realloc(This->records, 2 * This->allocated * sizeof(*This->records)); + if (!new_ptr) + return E_OUTOFMEMORY; + + This->records = new_ptr; + This->allocated *= 2; + }
+ entry = This->records + This->count; entry->info = *pErrorInfo; if(pdispparams) entry->dispparams = *pdispparams; @@ -245,7 +262,7 @@ static HRESULT WINAPI errorrec_AddErrorRecord(IErrorRecords *iface, ERRORINFO *p IUnknown_AddRef(entry->unknown); entry->lookupID = dwDynamicErrorID;
- list_add_head(&This->errors, &entry->entry); + This->count++;
return S_OK; } @@ -260,7 +277,7 @@ static HRESULT WINAPI errorrec_GetBasicErrorInfo(IErrorRecords *iface, ULONG ulR if(!pErrorInfo) return E_INVALIDARG;
- if(ulRecordNum > list_count(&This->errors)) + if(ulRecordNum > This->count) return DB_E_BADRECORDNUM;
return E_NOTIMPL; @@ -278,7 +295,7 @@ static HRESULT WINAPI errorrec_GetCustomErrorObject(IErrorRecords *iface, ULONG
*ppObject = NULL;
- if(ulRecordNum > list_count(&This->errors)) + if(ulRecordNum > This->count) return DB_E_BADRECORDNUM;
return E_NOTIMPL; @@ -294,7 +311,7 @@ static HRESULT WINAPI errorrec_GetErrorInfo(IErrorRecords *iface, ULONG ulRecord if (!ppErrorInfo) return E_INVALIDARG;
- if(ulRecordNum > list_count(&This->errors)) + if(ulRecordNum > This->count) return DB_E_BADRECORDNUM;
return E_NOTIMPL; @@ -310,24 +327,24 @@ static HRESULT WINAPI errorrec_GetErrorParameters(IErrorRecords *iface, ULONG ul if (!pdispparams) return E_INVALIDARG;
- if(ulRecordNum > list_count(&This->errors)) + if(ulRecordNum > This->count) return DB_E_BADRECORDNUM;
return E_NOTIMPL; }
-static HRESULT WINAPI errorrec_GetRecordCount(IErrorRecords *iface, ULONG *records) +static HRESULT WINAPI errorrec_GetRecordCount(IErrorRecords *iface, ULONG *count) { ErrorInfoImpl *This = impl_from_IErrorRecords(iface);
- TRACE("(%p)->(%p)\n", This, records); + TRACE("(%p)->(%p)\n", This, count);
- if(!records) + if(!count) return E_INVALIDARG;
- *records = list_count(&This->errors); + *count = This->count;
- TRACE("<--(%d)\n", *records); + TRACE("<--(%u)\n", *count);
return S_OK; } @@ -362,7 +379,9 @@ HRESULT create_error_info(IUnknown *outer, void **obj) This->IErrorRecords_iface.lpVtbl = &ErrorRecordsVtbl; This->ref = 1;
- list_init(&This->errors); + This->records = NULL; + This->allocated = 0; + This->count = 0;
*obj = &This->IErrorInfo_iface;
diff --git a/dlls/oledb32/oledb_private.h b/dlls/oledb32/oledb_private.h index 1422b0b..8b1a40f 100644 --- a/dlls/oledb32/oledb_private.h +++ b/dlls/oledb32/oledb_private.h @@ -33,6 +33,11 @@ static inline void *heap_alloc_zero(size_t len) return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); }
+static inline void *heap_realloc(void *mem, size_t len) +{ + return HeapReAlloc(GetProcessHeap(), 0, mem, len); +} + static inline void *heap_realloc_zero(void *mem, size_t len) { return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem, len);