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
7f23c57d
Commit
7f23c57d
authored
Jun 24, 2014
by
Piotr Caban
Committed by
Alexandre Julliard
Jun 24, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msvcr100: Add critical_section class implementation.
parent
dab64179
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
132 additions
and
34 deletions
+132
-34
lock.c
dlls/msvcrt/lock.c
+129
-31
main.c
dlls/msvcrt/main.c
+2
-2
msvcrt.h
dlls/msvcrt/msvcrt.h
+1
-1
No files found.
dlls/msvcrt/lock.c
View file @
7f23c57d
...
...
@@ -83,30 +83,6 @@ void msvcrt_init_mt_locks(void)
}
/**********************************************************************
* msvcrt_free_mt_locks (internal)
*
* Uninitialize all mt locks. Assume that neither _lock or _unlock will
* be called once we're calling this routine (ie _LOCKTAB_LOCK can be deleted)
*
*/
void
msvcrt_free_mt_locks
(
void
)
{
int
i
;
TRACE
(
": uninitializing all mtlocks
\n
"
);
/* Uninitialize the table */
for
(
i
=
0
;
i
<
_TOTAL_LOCKS
;
i
++
)
{
if
(
lock_table
[
i
].
bInit
)
{
msvcrt_uninitialize_mlock
(
i
);
}
}
}
/**********************************************************************
* _lock (MSVCRT.@)
*/
void
CDECL
_lock
(
int
locknum
)
...
...
@@ -309,10 +285,24 @@ MSVCRT_bool __thiscall SpinWait__SpinOnce(SpinWait *this)
}
}
static
HANDLE
keyed_event
;
typedef
struct
cs_queue
{
struct
cs_queue
*
next
;
}
cs_queue
;
typedef
struct
{
void
*
unknown
[
3
];
void
*
head
;
ULONG_PTR
unk_thread_id
;
cs_queue
unk_active
;
#if _MSVCR_VER >= 110
void
*
unknown
[
2
];
int
unknown2
[
2
];
#else
void
*
unknown
[
1
];
#endif
cs_queue
*
head
;
void
*
tail
;
}
critical_section
;
...
...
@@ -321,7 +311,18 @@ typedef struct
DEFINE_THISCALL_WRAPPER
(
critical_section_ctor
,
4
)
critical_section
*
__thiscall
critical_section_ctor
(
critical_section
*
this
)
{
FIXME
(
"(%p) stub
\n
"
,
this
);
TRACE
(
"(%p)
\n
"
,
this
);
if
(
!
keyed_event
)
{
HANDLE
event
;
NtCreateKeyedEvent
(
&
event
,
GENERIC_READ
|
GENERIC_WRITE
,
NULL
,
0
);
if
(
InterlockedCompareExchangePointer
(
&
keyed_event
,
event
,
NULL
)
!=
NULL
)
NtClose
(
event
);
}
this
->
unk_thread_id
=
0
;
this
->
head
=
this
->
tail
=
NULL
;
return
this
;
}
...
...
@@ -330,7 +331,32 @@ critical_section* __thiscall critical_section_ctor(critical_section *this)
DEFINE_THISCALL_WRAPPER
(
critical_section_dtor
,
4
)
void
__thiscall
critical_section_dtor
(
critical_section
*
this
)
{
FIXME
(
"(%p) stub
\n
"
,
this
);
TRACE
(
"(%p)
\n
"
,
this
);
}
static
void
__cdecl
spin_wait_yield
(
void
)
{
Sleep
(
0
);
}
static
inline
void
spin_wait_for_next_cs
(
cs_queue
*
q
)
{
SpinWait
sw
;
if
(
q
->
next
)
return
;
SpinWait_ctor
(
&
sw
,
&
spin_wait_yield
);
SpinWait__Reset
(
&
sw
);
while
(
!
q
->
next
)
SpinWait__SpinOnce
(
&
sw
);
SpinWait_dtor
(
&
sw
);
}
static
inline
void
cs_set_head
(
critical_section
*
cs
,
cs_queue
*
q
)
{
cs
->
unk_thread_id
=
GetCurrentThreadId
();
cs
->
unk_active
.
next
=
q
->
next
;
cs
->
head
=
&
cs
->
unk_active
;
}
/* ?lock@critical_section@Concurrency@@QAEXXZ */
...
...
@@ -338,7 +364,26 @@ void __thiscall critical_section_dtor(critical_section *this)
DEFINE_THISCALL_WRAPPER
(
critical_section_lock
,
4
)
void
__thiscall
critical_section_lock
(
critical_section
*
this
)
{
FIXME
(
"(%p) stub
\n
"
,
this
);
cs_queue
q
,
*
last
;
TRACE
(
"(%p)
\n
"
,
this
);
if
(
this
->
unk_thread_id
==
GetCurrentThreadId
())
{
FIXME
(
"throw exception
\n
"
);
return
;
}
q
.
next
=
NULL
;
last
=
InterlockedExchangePointer
(
&
this
->
tail
,
&
q
);
if
(
last
)
{
last
->
next
=
&
q
;
NtWaitForKeyedEvent
(
keyed_event
,
&
q
,
0
,
NULL
);
}
this
->
unk_active
.
next
=
NULL
;
if
(
InterlockedCompareExchangePointer
(
&
this
->
tail
,
&
this
->
unk_active
,
&
q
)
!=
&
q
)
spin_wait_for_next_cs
(
&
q
);
cs_set_head
(
this
,
&
q
);
}
/* ?try_lock@critical_section@Concurrency@@QAE_NXZ */
...
...
@@ -346,7 +391,24 @@ void __thiscall critical_section_lock(critical_section *this)
DEFINE_THISCALL_WRAPPER
(
critical_section_try_lock
,
4
)
MSVCRT_bool
__thiscall
critical_section_try_lock
(
critical_section
*
this
)
{
FIXME
(
"(%p) stub
\n
"
,
this
);
cs_queue
q
;
TRACE
(
"(%p)
\n
"
,
this
);
if
(
this
->
unk_thread_id
==
GetCurrentThreadId
())
{
FIXME
(
"throw exception
\n
"
);
return
FALSE
;
}
q
.
next
=
NULL
;
if
(
!
InterlockedCompareExchangePointer
(
&
this
->
tail
,
&
q
,
NULL
))
{
this
->
unk_active
.
next
=
NULL
;
if
(
InterlockedCompareExchangePointer
(
&
this
->
tail
,
&
this
->
unk_active
,
&
q
)
!=
&
q
)
spin_wait_for_next_cs
(
&
q
);
cs_set_head
(
this
,
&
q
);
return
TRUE
;
}
return
FALSE
;
}
...
...
@@ -355,7 +417,15 @@ MSVCRT_bool __thiscall critical_section_try_lock(critical_section *this)
DEFINE_THISCALL_WRAPPER
(
critical_section_unlock
,
4
)
void
__thiscall
critical_section_unlock
(
critical_section
*
this
)
{
FIXME
(
"(%p) stub
\n
"
,
this
);
TRACE
(
"(%p)
\n
"
,
this
);
this
->
unk_thread_id
=
0
;
this
->
head
=
NULL
;
if
(
InterlockedCompareExchangePointer
(
&
this
->
tail
,
NULL
,
&
this
->
unk_active
)
==
&
this
->
unk_active
)
return
;
spin_wait_for_next_cs
(
&
this
->
unk_active
);
NtReleaseKeyedEvent
(
keyed_event
,
this
->
unk_active
.
next
,
0
,
NULL
);
}
/* ?native_handle@critical_section@Concurrency@@QAEAAV12@XZ */
...
...
@@ -394,3 +464,31 @@ void __thiscall critical_section_scoped_lock_dtor(critical_section_scoped_lock *
critical_section_unlock
(
this
->
cs
);
}
#endif
/**********************************************************************
* msvcrt_free_locks (internal)
*
* Uninitialize all mt locks. Assume that neither _lock or _unlock will
* be called once we're calling this routine (ie _LOCKTAB_LOCK can be deleted)
*
*/
void
msvcrt_free_locks
(
void
)
{
int
i
;
TRACE
(
": uninitializing all mtlocks
\n
"
);
/* Uninitialize the table */
for
(
i
=
0
;
i
<
_TOTAL_LOCKS
;
i
++
)
{
if
(
lock_table
[
i
].
bInit
)
{
msvcrt_uninitialize_mlock
(
i
);
}
}
#if _MSVCR_VER >= 100
if
(
keyed_event
)
NtClose
(
keyed_event
);
#endif
}
dlls/msvcrt/main.c
View file @
7f23c57d
...
...
@@ -106,7 +106,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
}
msvcrt_init_mt_locks
();
if
(
!
msvcrt_init_locale
())
{
msvcrt_free_
mt_
locks
();
msvcrt_free_locks
();
msvcrt_free_tls_mem
();
msvcrt_destroy_heap
();
return
FALSE
;
...
...
@@ -130,7 +130,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
msvcrt_free_io
();
if
(
lpvReserved
)
break
;
msvcrt_free_popen_data
();
msvcrt_free_
mt_
locks
();
msvcrt_free_locks
();
msvcrt_free_console
();
msvcrt_free_args
();
msvcrt_free_signals
();
...
...
dlls/msvcrt/msvcrt.h
View file @
7f23c57d
...
...
@@ -261,7 +261,7 @@ typedef void (__cdecl *free_func_t)(void*);
/* Setup and teardown multi threaded locks */
extern
void
msvcrt_init_mt_locks
(
void
)
DECLSPEC_HIDDEN
;
extern
void
msvcrt_free_
mt_
locks
(
void
)
DECLSPEC_HIDDEN
;
extern
void
msvcrt_free_locks
(
void
)
DECLSPEC_HIDDEN
;
extern
void
msvcrt_init_exception
(
void
*
)
DECLSPEC_HIDDEN
;
extern
BOOL
msvcrt_init_locale
(
void
)
DECLSPEC_HIDDEN
;
...
...
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