Hans Leidekker : wbemprox: Add reference counting to the table structure.

Alexandre Julliard julliard at winehq.org
Wed Oct 10 15:07:52 CDT 2012


Module: wine
Branch: master
Commit: ef6fa2b9f2e5141000d8602625159dfe45867fe6
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ef6fa2b9f2e5141000d8602625159dfe45867fe6

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Wed Oct 10 12:01:44 2012 +0200

wbemprox: Add reference counting to the table structure.

---

 dlls/wbemprox/class.c            |   35 ++++++++++++++++++++---------------
 dlls/wbemprox/query.c            |    4 ++--
 dlls/wbemprox/services.c         |    8 +++++---
 dlls/wbemprox/table.c            |   37 ++++++++++++++++++++++++++++++-------
 dlls/wbemprox/wbemprox_private.h |    8 +++++---
 5 files changed, 62 insertions(+), 30 deletions(-)

diff --git a/dlls/wbemprox/class.c b/dlls/wbemprox/class.c
index 5a70e9d..5bbd6aa 100644
--- a/dlls/wbemprox/class.c
+++ b/dlls/wbemprox/class.c
@@ -382,11 +382,14 @@ static HRESULT WINAPI class_object_Put(
 
     if (co->record)
     {
-        struct table *table = get_table( co->name );
+        struct table *table = grab_table( co->name );
         UINT index;
         HRESULT hr;
 
-        if ((hr = get_column_index( table, wszName, &index )) != S_OK) return hr;
+        if (!table) return WBEM_E_FAILED;
+        hr = get_column_index( table, wszName, &index );
+        release_table( table );
+        if (hr != S_OK) return hr;
         return record_set_value( co->record, index, pVal );
     }
     return put_propval( ec->query->view, co->index, wszName, pVal, Type );
@@ -450,18 +453,18 @@ static HRESULT WINAPI class_object_Next(
     struct class_object *co = impl_from_IWbemClassObject( iface );
     struct enum_class_object *ec = impl_from_IEnumWbemClassObject( co->iter );
     struct view *view = ec->query->view;
-    const WCHAR *property;
+    BSTR property;
     HRESULT hr;
 
     TRACE("%p, %08x, %p, %p, %p, %p\n", iface, lFlags, strName, pVal, pType, plFlavor);
 
     if (!(property = get_property_name( co->name, co->index_property ))) return WBEM_S_NO_MORE_DATA;
-    if (!(*strName = SysAllocString( property ))) return E_OUTOFMEMORY;
     if ((hr = get_propval( view, co->index, property, pVal, pType, plFlavor ) != S_OK))
     {
-        SysFreeString( *strName );
+        SysFreeString( property );
         return hr;
     }
+    *strName = property;
     co->index_property++;
     return S_OK;
 }
@@ -834,7 +837,7 @@ static HRESULT WINAPI class_object_NextMethod(
     IWbemClassObject **ppOutSignature)
 {
     struct class_object *co = impl_from_IWbemClassObject( iface );
-    const WCHAR *method;
+    BSTR method;
     HRESULT hr;
 
     TRACE("%p, %08x, %p, %p, %p\n", iface, lFlags, pstrName, ppInSignature, ppOutSignature);
@@ -842,18 +845,20 @@ static HRESULT WINAPI class_object_NextMethod(
     if (!(method = get_method_name( co->name, co->index_method ))) return WBEM_S_NO_MORE_DATA;
 
     hr = create_signature( co->name, method, PARAM_IN, ppInSignature );
-    if (hr != S_OK) return hr;
-
+    if (hr != S_OK)
+    {
+        SysFreeString( method );
+        return hr;
+    }
     hr = create_signature( co->name, method, PARAM_OUT, ppOutSignature );
-    if (hr != S_OK) IWbemClassObject_Release( *ppInSignature );
+    if (hr != S_OK)
+    {
+        SysFreeString( method );
+        IWbemClassObject_Release( *ppInSignature );
+    }
     else
     {
-        if (!(*pstrName = SysAllocString( method )))
-        {
-            IWbemClassObject_Release( *ppInSignature );
-            IWbemClassObject_Release( *ppOutSignature );
-            return E_OUTOFMEMORY;
-        }
+        *pstrName = method;
         co->index_method++;
     }
     return hr;
diff --git a/dlls/wbemprox/query.c b/dlls/wbemprox/query.c
index 223a373..8df09bc 100644
--- a/dlls/wbemprox/query.c
+++ b/dlls/wbemprox/query.c
@@ -37,7 +37,7 @@ HRESULT create_view( const struct property *proplist, const WCHAR *class,
 
     if (!view) return E_OUTOFMEMORY;
     view->proplist = proplist;
-    view->table    = get_table( class );
+    view->table    = grab_table( class );
     view->cond     = cond;
     view->result   = NULL;
     view->count    = 0;
@@ -47,7 +47,7 @@ HRESULT create_view( const struct property *proplist, const WCHAR *class,
 
 void destroy_view( struct view *view )
 {
-    free_table( view->table );
+    if (view->table) release_table( view->table );
     heap_free( view->result );
     heap_free( view );
 }
diff --git a/dlls/wbemprox/services.c b/dlls/wbemprox/services.c
index 5e9cec0..3f87d5b 100644
--- a/dlls/wbemprox/services.c
+++ b/dlls/wbemprox/services.c
@@ -578,7 +578,7 @@ static HRESULT WINAPI wbem_services_ExecMethod(
     IWbemClassObject **ppOutParams,
     IWbemCallResult **ppCallResult )
 {
-    const struct table *table;
+    struct table *table;
     class_method *func;
     struct path *path;
     HRESULT hr;
@@ -590,11 +590,13 @@ static HRESULT WINAPI wbem_services_ExecMethod(
 
     if ((hr = parse_path( strObjectPath, &path )) != S_OK) return hr;
 
-    table = get_table( path->class );
+    table = grab_table( path->class );
     free_path( path );
     if (!table) return WBEM_E_NOT_FOUND;
 
-    if ((hr = get_method( table, strMethodName, &func )) != S_OK) return hr;
+    hr = get_method( table, strMethodName, &func );
+    release_table( table );
+    if (hr != S_OK) return hr;
     return func( pInParams, ppOutParams );
 }
 
diff --git a/dlls/wbemprox/table.c b/dlls/wbemprox/table.c
index c414aa9..a49bf58 100644
--- a/dlls/wbemprox/table.c
+++ b/dlls/wbemprox/table.c
@@ -316,7 +316,12 @@ void free_table( struct table *table )
     }
 }
 
-struct table *get_table( const WCHAR *name )
+void release_table( struct table *table )
+{
+    if (!InterlockedDecrement( &table->refs )) free_table( table );
+}
+
+struct table *grab_table( const WCHAR *name )
 {
     struct table *table;
 
@@ -325,6 +330,8 @@ struct table *get_table( const WCHAR *name )
         if (!strcmpiW( table->name, name ))
         {
             if (table->fill && !table->data) table->fill( table );
+            InterlockedIncrement( &table->refs );
+            TRACE("returning %p\n", table);
             return table;
         }
     }
@@ -344,6 +351,7 @@ struct table *create_table( const WCHAR *name, UINT num_cols, const struct colum
     table->data     = data;
     table->fill     = fill;
     table->flags    = TABLE_FLAG_DYNAMIC;
+    table->refs     = 0;
     list_init( &table->entry );
     return table;
 }
@@ -361,41 +369,56 @@ BOOL add_table( struct table *table )
         }
     }
     list_add_tail( table_list, &table->entry );
+    TRACE("added %p\n", table);
     return TRUE;
 }
 
-const WCHAR *get_method_name( const WCHAR *class, UINT index )
+BSTR get_method_name( const WCHAR *class, UINT index )
 {
     struct table *table;
     UINT i, count = 0;
+    BSTR ret;
 
-    if (!(table = get_table( class ))) return NULL;
+    if (!(table = grab_table( class ))) return NULL;
 
     for (i = 0; i < table->num_cols; i++)
     {
         if (table->columns[i].type & COL_FLAG_METHOD)
         {
-            if (index == count) return table->columns[i].name;
+            if (index == count)
+            {
+                ret = SysAllocString( table->columns[i].name );
+                release_table( table );
+                return ret;
+            }
             count++;
         }
     }
+    release_table( table );
     return NULL;
 }
 
-const WCHAR *get_property_name( const WCHAR *class, UINT index )
+BSTR get_property_name( const WCHAR *class, UINT index )
 {
     struct table *table;
     UINT i, count = 0;
+    BSTR ret;
 
-    if (!(table = get_table( class ))) return NULL;
+    if (!(table = grab_table( class ))) return NULL;
 
     for (i = 0; i < table->num_cols; i++)
     {
         if (!(table->columns[i].type & COL_FLAG_METHOD))
         {
-            if (index == count) return table->columns[i].name;
+            if (index == count)
+            {
+                ret = SysAllocString( table->columns[i].name );
+                release_table( table );
+                return ret;
+            }
             count++;
         }
     }
+    release_table( table );
     return NULL;
 }
diff --git a/dlls/wbemprox/wbemprox_private.h b/dlls/wbemprox/wbemprox_private.h
index b99897e..b0e9933 100644
--- a/dlls/wbemprox/wbemprox_private.h
+++ b/dlls/wbemprox/wbemprox_private.h
@@ -57,6 +57,7 @@ struct table
     void (*fill)(struct table *);
     UINT flags;
     struct list entry;
+    LONG refs;
 };
 
 struct property
@@ -151,7 +152,8 @@ HRESULT create_view( const struct property *, const WCHAR *, const struct expr *
                      struct view ** ) DECLSPEC_HIDDEN;
 void destroy_view( struct view * ) DECLSPEC_HIDDEN;
 void init_table_list( void ) DECLSPEC_HIDDEN;
-struct table *get_table( const WCHAR * ) DECLSPEC_HIDDEN;
+struct table *grab_table( const WCHAR * ) DECLSPEC_HIDDEN;
+void release_table( struct table * ) DECLSPEC_HIDDEN;
 struct table *create_table( const WCHAR *, UINT, const struct column *, UINT,
                             BYTE *, void (*)(struct table *)) DECLSPEC_HIDDEN;
 BOOL add_table( struct table * ) DECLSPEC_HIDDEN;
@@ -169,8 +171,8 @@ HRESULT put_propval( const struct view *, UINT, const WCHAR *, VARIANT *, CIMTYP
 HRESULT variant_to_longlong( VARIANT *, LONGLONG *, CIMTYPE * ) DECLSPEC_HIDDEN;
 HRESULT get_properties( const struct view *, SAFEARRAY ** ) DECLSPEC_HIDDEN;
 HRESULT get_object( const WCHAR *, IWbemClassObject ** ) DECLSPEC_HIDDEN;
-const WCHAR *get_method_name( const WCHAR *, UINT ) DECLSPEC_HIDDEN;
-const WCHAR *get_property_name( const WCHAR *, UINT ) DECLSPEC_HIDDEN;
+BSTR get_method_name( const WCHAR *, UINT ) DECLSPEC_HIDDEN;
+BSTR get_property_name( const WCHAR *, UINT ) DECLSPEC_HIDDEN;
 
 HRESULT WbemLocator_create(IUnknown *, LPVOID *) DECLSPEC_HIDDEN;
 HRESULT WbemServices_create(IUnknown *, const WCHAR *, LPVOID *) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list