Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
42d12558
Commit
42d12558
authored
Feb 13, 1999
by
Sylvain St.Germain
Committed by
Alexandre Julliard
Feb 13, 1999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implementation of a simple linked list (static) that stores and counts
references to COM objects.
parent
15382c5e
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
279 additions
and
3 deletions
+279
-3
compobj.c
ole/compobj.c
+279
-3
No files found.
ole/compobj.c
View file @
42d12558
...
...
@@ -4,6 +4,7 @@
* Copyright 1995 Martin von Loewis
* Copyright 1998 Justin Bradford
* Copyright 1999 Francis Beaudet
* Copyright 1999 Sylvain St-Germain
*/
#include "config.h"
...
...
@@ -45,6 +46,70 @@
#include "objbase.h"
/****************************************************************************
* COM External Lock structures and methods declaration
*
* This api provides a linked list to managed external references to
* COM objects.
*
* The public interface consists of three calls:
* COM_ExternalLockAddRef
* COM_ExternalLockRelease
* COM_ExternalLockFreeList
*/
#define EL_END_OF_LIST 0
#define EL_NOT_FOUND 0
/*
* Declaration of the static structure that manage the
* external lock to COM objects.
*/
typedef
struct
COM_ExternalLock
COM_ExternalLock
;
typedef
struct
COM_ExternalLockList
COM_ExternalLockList
;
struct
COM_ExternalLock
{
IUnknown
*
pUnk
;
/* IUnknown referenced */
ULONG
uRefCount
;
/* external lock counter to IUnknown object*/
COM_ExternalLock
*
next
;
/* Pointer to next element in list */
};
struct
COM_ExternalLockList
{
COM_ExternalLock
*
head
;
/* head of list */
};
/*
* Declaration and initialization of the static structure that manages
* the external lock to COM objects.
*/
static
COM_ExternalLockList
elList
=
{
EL_END_OF_LIST
};
/*
* Public Interface to the external lock list
*/
static
void
COM_ExternalLockFreeList
();
static
void
COM_ExternalLockAddRef
(
IUnknown
*
pUnk
);
static
void
COM_ExternalLockRelease
(
IUnknown
*
pUnk
,
BOOL32
bRelAll
);
void
COM_ExternalLockDump
();
/* testing purposes, not static to avoid warning */
/*
* Private methods used to managed the linked list
*/
static
BOOL32
COM_ExternalLockInsert
(
IUnknown
*
pUnk
);
static
void
COM_ExternalLockDelete
(
COM_ExternalLock
*
element
);
static
COM_ExternalLock
*
COM_ExternalLockFind
(
IUnknown
*
pUnk
);
static
COM_ExternalLock
*
COM_ExternalLockLocate
(
COM_ExternalLock
*
element
,
IUnknown
*
pUnk
);
/****************************************************************************
* This section defines variables internal to the COM module.
*
* TODO: Most of these things will have to be made thread-safe.
...
...
@@ -260,6 +325,11 @@ void WINAPI CoUninitialize32(void)
* This will free the loaded COM Dlls.
*/
CoFreeAllLibraries
();
/*
* This will free list of external references to COM objects.
*/
COM_ExternalLockFreeList
();
}
}
...
...
@@ -1420,9 +1490,26 @@ HRESULT WINAPI CoLockObjectExternal16(
HRESULT
WINAPI
CoLockObjectExternal32
(
LPUNKNOWN
pUnk
,
/* [in] object to be locked */
BOOL32
fLock
,
/* [in] do lock */
BOOL32
fLastUnlockReleases
/* [in] ? */
)
{
FIXME
(
ole
,
"(%p,%d,%d),stub!
\n
"
,
pUnk
,
fLock
,
fLastUnlockReleases
);
BOOL32
fLastUnlockReleases
)
/* [in] unlock all */
{
if
(
fLock
)
{
/*
* Increment the external lock coutner, COM_ExternalLockAddRef also
* increment the object's internal lock counter.
*/
COM_ExternalLockAddRef
(
pUnk
);
}
else
{
/*
* Decrement the external lock coutner, COM_ExternalLockRelease also
* decrement the object's internal lock counter.
*/
COM_ExternalLockRelease
(
pUnk
,
fLastUnlockReleases
);
}
return
S_OK
;
}
...
...
@@ -1460,3 +1547,192 @@ static void COM_RevokeAllClasses()
}
}
/****************************************************************************
* COM External Lock methods implementation
*/
/****************************************************************************
* Public - Method that increments the count for a IUnknown* in the linked
* list. The item is inserted if not already in the list.
*/
static
void
COM_ExternalLockAddRef
(
IUnknown
*
pUnk
)
{
COM_ExternalLock
*
externalLock
=
COM_ExternalLockFind
(
pUnk
);
if
(
externalLock
==
EL_NOT_FOUND
)
COM_ExternalLockInsert
(
pUnk
);
else
{
externalLock
->
uRefCount
++
;
/* add an external lock */
IUnknown_AddRef
(
pUnk
);
/* add a local lock as well */
}
}
/****************************************************************************
* Public - Method that decrements the count for a IUnknown* in the linked
* list. The item is removed from the list if its count end up at zero or if
* bRelAll is TRUE.
*/
static
void
COM_ExternalLockRelease
(
IUnknown
*
pUnk
,
BOOL32
bRelAll
)
{
COM_ExternalLock
*
externalLock
=
COM_ExternalLockFind
(
pUnk
);
if
(
externalLock
!=
EL_NOT_FOUND
)
{
do
{
externalLock
->
uRefCount
--
;
/* release external locks */
IUnknown_Release
(
pUnk
);
/* release local locks as well */
if
(
bRelAll
==
FALSE
)
break
;
/* perform single release */
}
while
(
externalLock
->
uRefCount
>
0
);
if
(
externalLock
->
uRefCount
==
0
)
/* get rid of the list entry */
COM_ExternalLockDelete
(
externalLock
);
}
}
/****************************************************************************
* Public - Method that frees the content of the list.
*/
static
void
COM_ExternalLockFreeList
()
{
COM_ExternalLock
*
head
;
do
{
head
=
elList
.
head
;
/* grab it be the head */
COM_ExternalLockDelete
(
head
);
/* get rid of the head stuff */
head
=
elList
.
head
;
/* get the new head... */
}
while
(
head
!=
EL_END_OF_LIST
);
/* repeat as long as we have heads */
}
/****************************************************************************
* Public - Method that dump the content of the list.
*/
void
COM_ExternalLockDump
()
{
COM_ExternalLock
*
current
=
elList
.
head
;
printf
(
"
\n
External lock list contains:
\n
"
);
while
(
current
!=
EL_END_OF_LIST
)
{
printf
(
"
\t
%p with %lu references count.
\n
"
,
current
->
pUnk
,
current
->
uRefCount
);
/* Skip to the next item */
current
=
current
->
next
;
}
}
/****************************************************************************
* Internal - Find a IUnknown* in the linked list
*/
static
COM_ExternalLock
*
COM_ExternalLockFind
(
IUnknown
*
pUnk
)
{
return
COM_ExternalLockLocate
(
elList
.
head
,
pUnk
);
}
/****************************************************************************
* Internal - Recursivity agent for IUnknownExternalLockList_Find
*/
static
COM_ExternalLock
*
COM_ExternalLockLocate
(
COM_ExternalLock
*
element
,
IUnknown
*
pUnk
)
{
if
(
element
==
EL_END_OF_LIST
)
return
EL_NOT_FOUND
;
else
if
(
element
->
pUnk
==
pUnk
)
/* We found it */
return
element
;
else
/* Not the right guy, keep on looking */
return
COM_ExternalLockLocate
(
element
->
next
,
pUnk
);
}
/****************************************************************************
* Internal - Insert a new IUnknown* to the linked list
*/
static
BOOL32
COM_ExternalLockInsert
(
IUnknown
*
pUnk
)
{
COM_ExternalLock
*
newLock
=
NULL
;
COM_ExternalLock
*
previousHead
=
NULL
;
/*
* Allocate space for the new storage object
*/
newLock
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
COM_ExternalLock
));
if
(
newLock
!=
NULL
)
{
if
(
elList
.
head
==
EL_END_OF_LIST
)
{
elList
.
head
=
newLock
;
/* The list is empty */
}
else
{
/*
* insert does it at the head
*/
previousHead
=
elList
.
head
;
elList
.
head
=
newLock
;
}
/*
* Set new list item data member
*/
newLock
->
pUnk
=
pUnk
;
newLock
->
uRefCount
=
1
;
newLock
->
next
=
previousHead
;
return
TRUE
;
}
else
return
FALSE
;
}
/****************************************************************************
* Internal - Method that removes an item from the linked list.
*/
static
void
COM_ExternalLockDelete
(
COM_ExternalLock
*
itemList
)
{
COM_ExternalLock
*
current
=
elList
.
head
;
if
(
current
==
itemList
)
{
/*
* this section handles the deletion of the first node
*/
elList
.
head
=
itemList
->
next
;
HeapFree
(
GetProcessHeap
(),
0
,
itemList
);
}
else
{
do
{
if
(
current
->
next
==
itemList
)
/* We found the item to free */
{
current
->
next
=
itemList
->
next
;
/* readjust the list pointers */
HeapFree
(
GetProcessHeap
(),
0
,
itemList
);
break
;
}
/* Skip to the next item */
current
=
current
->
next
;
}
while
(
current
!=
EL_END_OF_LIST
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment