Ignore:
Timestamp:
Jun 9, 2001, 4:50:26 PM (24 years ago)
Author:
sandervl
Message:

reference count (window + class objects) rewrite

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/user32/win32class.cpp

    r5472 r5935  
    1 /* $Id: win32class.cpp,v 1.24 2001-04-04 09:01:25 sandervl Exp $ */
     1/* $Id: win32class.cpp,v 1.25 2001-06-09 14:50:20 sandervl Exp $ */
    22/*
    33 * Win32 Window Class Managment Code for OS/2
     
    1010 *       Must all be changed if we want to support global app classes
    1111 *       that can be used by other apps. (low priority)
     12 *
     13 * NOTE: To access a class object, you must call FindClass. This method
     14 *       increases the reference count of the object. When you're done
     15 *       with the object, you MUST call the release method!
     16 *       This mechanism prevents premature destruction of objects when there
     17 *       are still clients using it.
    1218 *
    1319 * Project Odin Software License can be found in LICENSE.TXT
     
    3440//Win32WndClass methods:
    3541//******************************************************************************
    36 Win32WndClass::Win32WndClass(WNDCLASSEXA *wndclass, BOOL fUnicode) : GenericObject(&wndclasses, OBJTYPE_CLASS)
     42Win32WndClass::Win32WndClass(WNDCLASSEXA *wndclass, BOOL fUnicode)
     43                  : GenericObject(&wndclasses, &critsect)
    3744{
    3845  isUnicode = fUnicode;
     
    134141  else  userClassBytes = NULL;
    135142
    136   cWindows = 0;
    137143  hIconSm  = wndclass->hIconSm;
    138144}
     
    142148{
    143149  if(classNameA) {
    144     dprintf(("Win32WndClass dtor, destroy class %s\n", classNameA));
     150      dprintf(("Win32WndClass dtor, destroy class %s\n", classNameA));
    145151  }
    146152
    147153  //SvL: Don't delete global classes
    148154  if(classNameA && !(windowStyle & CS_GLOBALCLASS)) {
    149     GlobalDeleteAtom(classAtom);
     155      GlobalDeleteAtom(classAtom);
    150156  }
    151157
     
    156162  if(classNameW)        free(classNameW);
    157163  if(menuNameA && HIWORD(menuNameA)) {
    158         free(menuNameA);
    159         assert(menuNameW);
    160         free(menuNameW);
     164      free(menuNameA);
     165      assert(menuNameW);
     166      free(menuNameW);
    161167  }
    162168}
     
    187193}
    188194//******************************************************************************
     195//Locates class in linked list and increases reference count (if found)
     196//Class object must be unreferenced after usage
    189197//******************************************************************************
    190198Win32WndClass *Win32WndClass::FindClass(HINSTANCE hInstance, LPSTR id)
    191199{
    192   enterMutex(OBJTYPE_CLASS);
     200  lock(&critsect);
    193201
    194202  Win32WndClass *wndclass = (Win32WndClass *)wndclasses;
    195203
    196204  if(wndclass == NULL) {
    197         leaveMutex(OBJTYPE_CLASS);
     205        unlock(&critsect);
    198206        return(NULL);
    199207  }
     
    202210//CB: read comment below!
    203211        if(lstrcmpiA(wndclass->classNameA, id) == 0 && wndclass->hInstance == hInstance) {
    204                 leaveMutex(OBJTYPE_CLASS);
     212                wndclass->addRef();
     213                unlock(&critsect);
    205214                return(wndclass);
    206215        }
     
    214223                                   wndclass->hInstance == hInstance)
    215224                                {
    216                                     leaveMutex(OBJTYPE_CLASS);
     225                                    wndclass->addRef();
     226                                    unlock(&critsect);
    217227                                    return(wndclass);
    218228                                }
     
    226236//CB: need more code to compare instance; convert 0 to exe module handle
    227237        if(wndclass->classAtom == (DWORD)id /*&& wndclass->hInstance == hInstance*/) {
    228                 leaveMutex(OBJTYPE_CLASS);
     238                wndclass->addRef();
     239                unlock(&critsect);
    229240                return(wndclass);
    230241        }
     
    233244                while(wndclass != NULL) {
    234245                        if(wndclass->classAtom == (DWORD)id /* && wndclass->hInstance == hInstance*/) {
    235                                 leaveMutex(OBJTYPE_CLASS);
     246                                wndclass->addRef();
     247                                unlock(&critsect);
    236248                                return(wndclass);
    237249                        }
     
    240252        }
    241253  }
    242   leaveMutex(OBJTYPE_CLASS);
     254  unlock(&critsect);
    243255  dprintf(("Class %X (inst %X) not found!", id, hInstance));
    244256  return(NULL);
    245257}
    246258//******************************************************************************
     259//Locates class in linked list and increases reference count (if found)
     260//Class object must be unreferenced after usage
    247261//******************************************************************************
    248262Win32WndClass *Win32WndClass::FindClass(HINSTANCE hInstance, LPWSTR id)
     
    252266
    253267  if(HIWORD(id)) {
    254     lpszClassName = UnicodeToAsciiString((LPWSTR)id);
    255   }
    256   else  lpszClassName = (LPSTR)id;
     268       lpszClassName = UnicodeToAsciiString((LPWSTR)id);
     269  }
     270  else lpszClassName = (LPSTR)id;
    257271
    258272  winclass = FindClass(hInstance, lpszClassName);
     
    551565  wndclass = FindClass(hinst, id);
    552566  if(wndclass) {
    553         if(wndclass->GetWindowCount() != 0) {
     567        if(wndclass->getRefCount() != 1) {
     568            wndclass->markDeleted();
     569            RELEASE_CLASSOBJ(wndclass);
    554570            dprintf2(("Win32WndClass::UnregisterClassA class %x still has windows!!", id));
    555571            SetLastError(ERROR_CLASS_HAS_WINDOWS);
    556572            return FALSE;
    557573        }
     574        RELEASE_CLASSOBJ(wndclass);
    558575        delete wndclass;
    559576        SetLastError(ERROR_SUCCESS);
     
    566583//******************************************************************************
    567584//******************************************************************************
    568 GenericObject *Win32WndClass::wndclasses = NULL;
     585GenericObject   *Win32WndClass::wndclasses = NULL;
     586CRITICAL_SECTION Win32WndClass::critsect   = {0};
Note: See TracChangeset for help on using the changeset viewer.