Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
wine
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Package registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Alexey Alyaev
wine
Commits
bae5552a
Commit
bae5552a
authored
26 years ago
by
Stephane Lussier
Committed by
Alexandre Julliard
26 years ago
Browse files
Options
Downloads
Patches
Plain Diff
Implemented SendMessageTimeout() functions.
parent
ebe76b73
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
include/queue.h
+1
-1
1 addition, 1 deletion
include/queue.h
windows/message.c
+178
-156
178 additions, 156 deletions
windows/message.c
windows/queue.c
+31
-65
31 additions, 65 deletions
windows/queue.c
with
210 additions
and
222 deletions
include/queue.h
+
1
−
1
View file @
bae5552a
...
...
@@ -152,7 +152,7 @@ extern MESSAGEQUEUE *QUEUE_GetSysQueue(void);
extern
void
QUEUE_SetWakeBit
(
MESSAGEQUEUE
*
queue
,
WORD
bit
);
extern
void
QUEUE_ClearWakeBit
(
MESSAGEQUEUE
*
queue
,
WORD
bit
);
extern
void
QUEUE_ReceiveMessage
(
MESSAGEQUEUE
*
queue
);
extern
void
QUEUE_WaitBits
(
WORD
bits
);
extern
int
QUEUE_WaitBits
(
WORD
bits
,
DWORD
timeout
);
extern
void
QUEUE_IncPaintCount
(
HQUEUE16
hQueue
);
extern
void
QUEUE_DecPaintCount
(
HQUEUE16
hQueue
);
extern
void
QUEUE_IncTimerCount
(
HQUEUE16
hQueue
);
...
...
This diff is collapsed.
Click to expand it.
windows/message.c
+
178
−
156
View file @
bae5552a
...
...
@@ -44,7 +44,6 @@ DWORD MSG_WineStartTicks; /* Ticks at Wine startup */
static
UINT
doubleClickSpeed
=
452
;
/***********************************************************************
* MSG_CheckFilter
*/
...
...
@@ -617,16 +616,24 @@ UINT WINAPI GetDoubleClickTime(void)
/***********************************************************************
* MSG_SendMessage
* MSG_SendMessage
InterThread
*
* Implementation of an inter-task SendMessage.
* Return values:
* 0 if error or timeout
* 1 if successflul
*/
static
LRESULT
MSG_SendMessage
(
HQUEUE16
hDestQueue
,
HWND
hwnd
,
UINT
msg
,
WPARAM
wParam
,
LPARAM
lParam
,
WORD
flags
)
static
LRESULT
MSG_SendMessageInterThread
(
HQUEUE16
hDestQueue
,
HWND
hwnd
,
UINT
msg
,
WPARAM
wParam
,
LPARAM
lParam
,
DWORD
timeout
,
WORD
flags
,
LRESULT
*
pRes
)
{
MESSAGEQUEUE
*
queue
,
*
destQ
;
SMSG
*
smsg
;
LRESULT
lResult
=
0
;
LRESULT
retVal
=
1
;
*
pRes
=
0
;
if
(
IsTaskLocked16
()
||
!
IsWindow
(
hwnd
))
return
0
;
...
...
@@ -634,7 +641,6 @@ static LRESULT MSG_SendMessage( HQUEUE16 hDestQueue, HWND hwnd, UINT msg,
/* create a SMSG structure to hold SendMessage() parameters */
if
(
!
(
smsg
=
(
SMSG
*
)
HeapAlloc
(
SystemHeap
,
0
,
sizeof
(
SMSG
)
))
)
return
0
;
if
(
!
(
queue
=
(
MESSAGEQUEUE
*
)
QUEUE_Lock
(
GetFastQueue16
()
)))
return
0
;
if
(
!
(
destQ
=
(
MESSAGEQUEUE
*
)
QUEUE_Lock
(
hDestQueue
)))
...
...
@@ -671,7 +677,13 @@ static LRESULT MSG_SendMessage( HQUEUE16 hDestQueue, HWND hwnd, UINT msg,
if
(
THREAD_IsWin16
(
THREAD_Current
())
&&
THREAD_IsWin16
(
destQ
->
thdb
)
)
DirectedYield16
(
destQ
->
thdb
->
teb
.
htask16
);
QUEUE_WaitBits
(
QS_SMRESULT
);
if
(
QUEUE_WaitBits
(
QS_SMRESULT
,
timeout
)
==
0
)
{
/* return with timeout */
SetLastError
(
0
);
retVal
=
0
;
break
;
}
if
(
!
(
smsg
->
flags
&
SMSG_HAVE_RESULT
)
)
{
...
...
@@ -681,8 +693,8 @@ static LRESULT MSG_SendMessage( HQUEUE16 hDestQueue, HWND hwnd, UINT msg,
}
else
{
l
Res
ult
=
smsg
->
lResult
;
TRACE
(
sendmsg
,
"smResult = %08x
\n
"
,
(
unsigned
)
l
Res
ult
);
*
p
Res
=
smsg
->
lResult
;
TRACE
(
sendmsg
,
"smResult = %08x
\n
"
,
(
unsigned
)
*
p
Res
);
}
}
...
...
@@ -717,19 +729,11 @@ static LRESULT MSG_SendMessage( HQUEUE16 hDestQueue, HWND hwnd, UINT msg,
/* Note: the destination thread is in charge of removing the smsg from
the pending list */
/* sender thread is in charge of releasing smsg if it's not an
early reply */
if
(
!
(
smsg
->
flags
&
SMSG_EARLY_REPLY
)
)
{
HeapFree
(
SystemHeap
,
0
,
smsg
);
}
else
{
/* In the case of an early reply, sender thread will released the
smsg structure if the receiver thread is done (SMSG_RECEIVED set).
If the receiver thread isn't done, SMSG_RECEIVER_CLEANS_UP flag
is set, and it will be the receiver responsability to released
smsg */
/* In the case of an early reply (or a timeout), sender thread will
released the smsg structure if the receiver thread is done
(SMSG_RECEIVED set). If the receiver thread isn't done,
SMSG_RECEIVER_CLEANS_UP flag is set, and it will be the receiver
responsability to released smsg */
EnterCriticalSection
(
&
queue
->
cSection
);
if
(
smsg
->
flags
&
SMSG_RECEIVED
)
...
...
@@ -738,13 +742,13 @@ static LRESULT MSG_SendMessage( HQUEUE16 hDestQueue, HWND hwnd, UINT msg,
smsg
->
flags
|=
SMSG_RECEIVER_CLEANS
;
LeaveCriticalSection
(
&
queue
->
cSection
);
}
QUEUE_Unlock
(
queue
);
QUEUE_Unlock
(
destQ
);
TRACE
(
sendmsg
,
"done!
\n
"
);
return
lResult
;
return
retVal
;
}
...
...
@@ -772,15 +776,15 @@ BOOL WINAPI ReplyMessage( LRESULT result )
while
((
smsg
=
queue
->
smWaiting
)
!=
0
)
{
senderQ
=
(
MESSAGEQUEUE
*
)
QUEUE_Lock
(
smsg
->
hSrcQueue
);
if
(
!
senderQ
)
goto
ReplyMessageEnd
;
/* if message has already been reply, continue the loop of receving
message */
if
(
smsg
->
flags
&
SMSG_ALREADY_REPLIED
)
goto
ReplyMessageDone
;
senderQ
=
(
MESSAGEQUEUE
*
)
QUEUE_Lock
(
smsg
->
hSrcQueue
);
if
(
!
senderQ
)
goto
ReplyMessageDone
;
/* if send message pending, processed it */
if
(
queue
->
wakeBits
&
QS_SENDMESSAGE
)
{
...
...
@@ -793,7 +797,7 @@ BOOL WINAPI ReplyMessage( LRESULT result )
}
if
(
!
smsg
)
goto
ReplyMessage
Done
;
goto
ReplyMessage
End
;
smsg
->
lResult
=
result
;
smsg
->
flags
|=
SMSG_ALREADY_REPLIED
;
...
...
@@ -805,12 +809,6 @@ BOOL WINAPI ReplyMessage( LRESULT result )
TRACE
(
sendmsg
,
"
\t
rpm: smResult = %08lx
\n
"
,
(
long
)
result
);
/* remove smsg from the waiting list, if it's not an early reply */
/* it is important to leave it in the waiting list if it's an early
reply, to be protected aginst multiple call to ReplyMessage() */
if
(
!
(
smsg
->
flags
&
SMSG_EARLY_REPLY
)
)
QUEUE_RemoveSMSG
(
queue
,
SM_WAITING_LIST
,
smsg
);
EnterCriticalSection
(
&
senderQ
->
cSection
);
smsg
->
flags
|=
SMSG_HAVE_RESULT
;
...
...
@@ -827,6 +825,30 @@ BOOL WINAPI ReplyMessage( LRESULT result )
ret
=
TRUE
;
ReplyMessageDone:
if
(
smsg
->
flags
&
SMSG_SENDING_REPLY
)
{
/* remove msg from the waiting list, since this is the last
ReplyMessage */
QUEUE_RemoveSMSG
(
queue
,
SM_WAITING_LIST
,
smsg
);
EnterCriticalSection
(
&
senderQ
->
cSection
);
/* tell the sender we're all done with smsg structure */
smsg
->
flags
|=
SMSG_RECEIVED
;
/* sender will set SMSG_RECEIVER_CLEANS_UP if it wants the
receiver to clean up smsg, it could only happens when there is
an early reply or a timeout */
if
(
smsg
->
flags
&
SMSG_RECEIVER_CLEANS
)
{
TRACE
(
sendmsg
,
"Receiver cleans up!
\n
"
);
HeapFree
(
SystemHeap
,
0
,
smsg
);
}
LeaveCriticalSection
(
&
senderQ
->
cSection
);
}
ReplyMessageEnd:
if
(
senderQ
)
QUEUE_Unlock
(
senderQ
);
if
(
queue
)
...
...
@@ -984,7 +1006,7 @@ static BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, DWORD first, DWORD last,
return
FALSE
;
}
msgQueue
->
wakeMask
=
mask
;
QUEUE_WaitBits
(
mask
);
QUEUE_WaitBits
(
mask
,
INFINITE
);
QUEUE_Unlock
(
msgQueue
);
}
...
...
@@ -1352,26 +1374,50 @@ BOOL16 WINAPI PostAppMessage16( HTASK16 hTask, UINT16 message, WPARAM16 wParam,
return
QUEUE_AddMsg
(
GetTaskQueue16
(
hTask
),
&
msg
,
0
);
}
/************************************************************************
* MSG_CallWndProcHook32
*/
static
void
MSG_CallWndProcHook
(
LPMSG
pmsg
,
BOOL
bUnicode
)
{
CWPSTRUCT
cwp
;
cwp
.
lParam
=
pmsg
->
lParam
;
cwp
.
wParam
=
pmsg
->
wParam
;
cwp
.
message
=
pmsg
->
message
;
cwp
.
hwnd
=
pmsg
->
hwnd
;
if
(
bUnicode
)
HOOK_CallHooksW
(
WH_CALLWNDPROC
,
HC_ACTION
,
1
,
(
LPARAM
)
&
cwp
);
else
HOOK_CallHooksA
(
WH_CALLWNDPROC
,
HC_ACTION
,
1
,
(
LPARAM
)
&
cwp
);
pmsg
->
lParam
=
cwp
.
lParam
;
pmsg
->
wParam
=
cwp
.
wParam
;
pmsg
->
message
=
cwp
.
message
;
pmsg
->
hwnd
=
cwp
.
hwnd
;
}
/***********************************************************************
* SendMessage16 (USER.111)
* MSG_SendMessage
*
* return values: 0 if timeout occurs
* 1 otherwise
*/
LRESULT
WINAPI
SendMessage16
(
HWND16
hwnd
,
UINT16
msg
,
WPARAM16
wParam
,
LPARAM
lParam
)
LRESULT
MSG_SendMessage
(
HWND
hwnd
,
UINT
msg
,
WPARAM
wParam
,
LPARAM
lParam
,
DWORD
timeout
,
WORD
flags
,
LRESULT
*
pRes
)
{
WND
*
wndPtr
;
WND
**
list
,
**
ppWnd
;
LRESULT
ret
;
LRESULT
ret
=
1
;
#ifdef CONFIG_IPC
MSG16
DDE_msg
=
{
hwnd
,
msg
,
wParam
,
lParam
};
if
(
DDE_SendMessage
(
&
DDE_msg
))
return
TRUE
;
#endif
/* CONFIG_IPC */
*
pRes
=
0
;
if
(
hwnd
==
HWND_BROADCAST
)
{
*
pRes
=
1
;
if
(
!
(
list
=
WIN_BuildWinArray
(
WIN_GetDesktop
(),
0
,
NULL
)))
return
TRUE
;
return
1
;
TRACE
(
msg
,
"HWND_BROADCAST !
\n
"
);
for
(
ppWnd
=
list
;
*
ppWnd
;
ppWnd
++
)
{
...
...
@@ -1381,23 +1427,30 @@ LRESULT WINAPI SendMessage16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
{
TRACE
(
msg
,
"BROADCAST Message to hWnd=%04x m=%04X w=%04lX l=%08lX !
\n
"
,
wndPtr
->
hwndSelf
,
msg
,
(
DWORD
)
wParam
,
lParam
);
SendMessage16
(
wndPtr
->
hwndSelf
,
msg
,
wParam
,
lParam
);
MSG_SendMessage
(
wndPtr
->
hwndSelf
,
msg
,
wParam
,
lParam
,
timeout
,
flags
,
pRes
);
}
}
HeapFree
(
SystemHeap
,
0
,
list
);
TRACE
(
msg
,
"End of HWND_BROADCAST !
\n
"
);
return
TRUE
;
return
1
;
}
if
(
HOOK_IsHooked
(
WH_CALLWNDPROC
))
{
if
(
flags
&
SMSG_UNICODE
)
MSG_CallWndProcHook
(
(
LPMSG
)
&
hwnd
,
TRUE
);
else
if
(
flags
&
SMSG_WIN32
)
MSG_CallWndProcHook
(
(
LPMSG
)
&
hwnd
,
FALSE
);
else
{
LPCWPSTRUCT16
pmsg
;
if
((
pmsg
=
SEGPTR_NEW
(
CWPSTRUCT16
)))
{
pmsg
->
hwnd
=
hwnd
;
pmsg
->
message
=
msg
;
pmsg
->
wParam
=
wParam
;
pmsg
->
hwnd
=
hwnd
&
0xffff
;
pmsg
->
message
=
msg
&
0xffff
;
pmsg
->
wParam
=
wParam
&
0xffff
;
pmsg
->
lParam
=
lParam
;
HOOK_CallHooks16
(
WH_CALLWNDPROC
,
HC_ACTION
,
1
,
(
LPARAM
)
SEGPTR_GET
(
pmsg
)
);
...
...
@@ -1408,6 +1461,7 @@ LRESULT WINAPI SendMessage16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
SEGPTR_FREE
(
pmsg
);
}
}
}
if
(
!
(
wndPtr
=
WIN_FindWndPtr
(
hwnd
)))
{
...
...
@@ -1417,40 +1471,57 @@ LRESULT WINAPI SendMessage16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
if
(
QUEUE_IsExitingQueue
(
wndPtr
->
hmemTaskQ
))
return
0
;
/* Don't send anything if the task is dying */
if
(
flags
&
SMSG_WIN32
)
SPY_EnterMessage
(
SPY_SENDMESSAGE
,
hwnd
,
msg
,
wParam
,
lParam
);
else
SPY_EnterMessage
(
SPY_SENDMESSAGE16
,
hwnd
,
msg
,
wParam
,
lParam
);
if
(
wndPtr
->
hmemTaskQ
!=
GetFastQueue16
())
ret
=
MSG_SendMessage
(
wndPtr
->
hmemTaskQ
,
hwnd
,
msg
,
wParam
,
lParam
,
0
);
ret
=
MSG_SendMessage
InterThread
(
wndPtr
->
hmemTaskQ
,
hwnd
,
msg
,
wParam
,
lParam
,
timeout
,
flags
,
pRes
);
else
ret
=
CallWindowProc16
(
(
WNDPROC16
)
wndPtr
->
winproc
,
{
/* Call the right CallWindowProc flavor */
if
(
flags
&
SMSG_UNICODE
)
*
pRes
=
CallWindowProcW
(
(
WNDPROC
)
wndPtr
->
winproc
,
hwnd
,
msg
,
wParam
,
lParam
);
else
if
(
flags
&
SMSG_WIN32
)
*
pRes
=
CallWindowProcA
(
(
WNDPROC
)
wndPtr
->
winproc
,
hwnd
,
msg
,
wParam
,
lParam
);
else
*
pRes
=
CallWindowProc16
(
(
WNDPROC16
)
wndPtr
->
winproc
,
(
HWND16
)
hwnd
,
(
UINT16
)
msg
,
(
WPARAM16
)
wParam
,
lParam
);
}
if
(
flags
&
SMSG_WIN32
)
SPY_ExitMessage
(
SPY_RESULT_OK
,
hwnd
,
msg
,
ret
);
else
SPY_ExitMessage
(
SPY_RESULT_OK16
,
hwnd
,
msg
,
ret
);
return
ret
;
}
/************************************************************************
* MSG_CallWndProcHook32
/***********************************************************************
* SendMessage16 (USER.111)
*/
static
void
MSG_CallWndProcHook
(
LPMSG
pmsg
,
BOOL
bUnicode
)
LRESULT
WINAPI
SendMessage16
(
HWND16
hwnd
,
UINT16
msg
,
WPARAM16
wParam
,
LPARAM
lParam
)
{
CWPSTRUCT
cwp
;
cwp
.
lParam
=
pmsg
->
lParam
;
cwp
.
wParam
=
pmsg
->
wParam
;
cwp
.
message
=
pmsg
->
message
;
cwp
.
hwnd
=
pmsg
->
hwnd
;
LRESULT
res
;
#ifdef CONFIG_IPC
MSG16
DDE_msg
=
{
hwnd
,
msg
,
wParam
,
lParam
};
if
(
DDE_SendMessage
(
&
DDE_msg
))
return
TRUE
;
#endif
/* CONFIG_IPC */
if
(
bUnicode
)
HOOK_CallHooksW
(
WH_CALLWNDPROC
,
HC_ACTION
,
1
,
(
LPARAM
)
&
cwp
);
else
HOOK_CallHooksA
(
WH_CALLWNDPROC
,
HC_ACTION
,
1
,
(
LPARAM
)
&
cwp
);
MSG_SendMessage
(
hwnd
,
msg
,
wParam
,
lParam
,
INFINITE
,
0
,
&
res
);
pmsg
->
lParam
=
cwp
.
lParam
;
pmsg
->
wParam
=
cwp
.
wParam
;
pmsg
->
message
=
cwp
.
message
;
pmsg
->
hwnd
=
cwp
.
hwnd
;
return
res
;
}
/**********************************************************************
* PostThreadMessage32A (USER32.422)
*
...
...
@@ -1499,49 +1570,13 @@ BOOL WINAPI PostThreadMessageW(DWORD idThread , UINT message,
*/
LRESULT
WINAPI
SendMessageA
(
HWND
hwnd
,
UINT
msg
,
WPARAM
wParam
,
LPARAM
lParam
)
{
WND
*
wndPtr
;
WND
**
list
,
**
ppWnd
;
LRESULT
ret
;
if
(
hwnd
==
HWND_BROADCAST
||
hwnd
==
HWND_TOPMOST
)
{
if
(
!
(
list
=
WIN_BuildWinArray
(
WIN_GetDesktop
(),
0
,
NULL
)))
return
TRUE
;
for
(
ppWnd
=
list
;
*
ppWnd
;
ppWnd
++
)
{
wndPtr
=
*
ppWnd
;
if
(
!
IsWindow
(
wndPtr
->
hwndSelf
))
continue
;
if
(
wndPtr
->
dwStyle
&
WS_POPUP
||
wndPtr
->
dwStyle
&
WS_CAPTION
)
SendMessageA
(
wndPtr
->
hwndSelf
,
msg
,
wParam
,
lParam
);
}
HeapFree
(
SystemHeap
,
0
,
list
);
return
TRUE
;
}
LRESULT
res
;
if
(
HOOK_IsHooked
(
WH_CALLWNDPROC
))
MSG_CallWndProcHook
(
(
LPMSG
)
&
hwnd
,
FALSE
);
if
(
!
(
wndPtr
=
WIN_FindWndPtr
(
hwnd
)))
{
WARN
(
msg
,
"invalid hwnd %08x
\n
"
,
hwnd
);
return
0
;
}
if
(
QUEUE_IsExitingQueue
(
wndPtr
->
hmemTaskQ
))
return
0
;
/* Don't send anything if the task is dying */
SPY_EnterMessage
(
SPY_SENDMESSAGE
,
hwnd
,
msg
,
wParam
,
lParam
);
if
(
wndPtr
->
hmemTaskQ
!=
GetFastQueue16
())
ret
=
MSG_SendMessage
(
wndPtr
->
hmemTaskQ
,
hwnd
,
msg
,
wParam
,
lParam
,
SMSG_WIN32
);
else
ret
=
CallWindowProcA
(
(
WNDPROC
)
wndPtr
->
winproc
,
hwnd
,
msg
,
wParam
,
lParam
);
MSG_SendMessage
(
hwnd
,
msg
,
wParam
,
lParam
,
INFINITE
,
SMSG_WIN32
,
&
res
);
SPY_ExitMessage
(
SPY_RESULT_OK
,
hwnd
,
msg
,
ret
);
return
ret
;
return
res
;
}
...
...
@@ -1572,47 +1607,12 @@ LRESULT WINAPI SendMessageW(
WPARAM
wParam
,
/* message parameter */
LPARAM
lParam
/* additional message parameter */
)
{
WND
*
wndPtr
;
WND
**
list
,
**
ppWnd
;
LRESULT
ret
;
if
(
hwnd
==
HWND_BROADCAST
||
hwnd
==
HWND_TOPMOST
)
{
if
(
!
(
list
=
WIN_BuildWinArray
(
WIN_GetDesktop
(),
0
,
NULL
)))
return
TRUE
;
for
(
ppWnd
=
list
;
*
ppWnd
;
ppWnd
++
)
{
wndPtr
=
*
ppWnd
;
if
(
!
IsWindow
(
wndPtr
->
hwndSelf
))
continue
;
if
(
wndPtr
->
dwStyle
&
WS_POPUP
||
wndPtr
->
dwStyle
&
WS_CAPTION
)
SendMessageW
(
wndPtr
->
hwndSelf
,
msg
,
wParam
,
lParam
);
}
HeapFree
(
SystemHeap
,
0
,
list
);
return
TRUE
;
}
if
(
HOOK_IsHooked
(
WH_CALLWNDPROC
))
MSG_CallWndProcHook
(
(
LPMSG
)
&
hwnd
,
TRUE
);
if
(
!
(
wndPtr
=
WIN_FindWndPtr
(
hwnd
)))
{
WARN
(
msg
,
"invalid hwnd %08x
\n
"
,
hwnd
);
return
0
;
}
if
(
QUEUE_IsExitingQueue
(
wndPtr
->
hmemTaskQ
))
return
0
;
/* Don't send anything if the task is dying */
LRESULT
res
;
SPY_EnterMessage
(
SPY_SENDMESSAGE
,
hwnd
,
msg
,
wParam
,
lParam
);
if
(
wndPtr
->
hmemTaskQ
!=
GetFastQueue16
())
ret
=
MSG_SendMessage
(
wndPtr
->
hmemTaskQ
,
hwnd
,
msg
,
wParam
,
lParam
,
SMSG_WIN32
|
SMSG_UNICODE
);
else
ret
=
CallWindowProcW
(
(
WNDPROC
)
wndPtr
->
winproc
,
hwnd
,
msg
,
wParam
,
lParam
);
MSG_SendMessage
(
hwnd
,
msg
,
wParam
,
lParam
,
INFINITE
,
SMSG_WIN32
|
SMSG_UNICODE
,
&
res
);
SPY_ExitMessage
(
SPY_RESULT_OK
,
hwnd
,
msg
,
ret
);
return
ret
;
return
res
;
}
...
...
@@ -1623,32 +1623,54 @@ LRESULT WINAPI SendMessageTimeout16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
LPARAM
lParam
,
UINT16
flags
,
UINT16
timeout
,
LPWORD
resultp
)
{
FIXME
(
sendmsg
,
"(...): semistub
\n
"
);
return
SendMessage16
(
hwnd
,
msg
,
wParam
,
lParam
);
LRESULT
ret
;
LRESULT
msgRet
;
/* FIXME: need support for SMTO_BLOCK */
ret
=
MSG_SendMessage
(
hwnd
,
msg
,
wParam
,
lParam
,
timeout
,
0
,
&
msgRet
);
*
resultp
=
(
WORD
)
msgRet
;
return
ret
;
}
/***********************************************************************
* SendMessageTimeout
32
A (USER32.457)
* SendMessageTimeoutA (USER32.457)
*/
LRESULT
WINAPI
SendMessageTimeoutA
(
HWND
hwnd
,
UINT
msg
,
WPARAM
wParam
,
LPARAM
lParam
,
UINT
flags
,
UINT
timeout
,
LPDWORD
resultp
)
{
FIXME
(
sendmsg
,
"(...): semistub
\n
"
);
return
SendMessageA
(
hwnd
,
msg
,
wParam
,
lParam
);
LRESULT
ret
;
LRESULT
msgRet
;
/* FIXME: need support for SMTO_BLOCK */
ret
=
MSG_SendMessage
(
hwnd
,
msg
,
wParam
,
lParam
,
timeout
,
SMSG_WIN32
,
&
msgRet
);
*
resultp
=
(
DWORD
)
msgRet
;
return
ret
;
}
/***********************************************************************
* SendMessageTimeout
32
W (USER32.458)
* SendMessageTimeoutW (USER32.458)
*/
LRESULT
WINAPI
SendMessageTimeoutW
(
HWND
hwnd
,
UINT
msg
,
WPARAM
wParam
,
LPARAM
lParam
,
UINT
flags
,
UINT
timeout
,
LPDWORD
resultp
)
{
FIXME
(
sendmsg
,
"(...): semistub
\n
"
);
return
SendMessageW
(
hwnd
,
msg
,
wParam
,
lParam
);
LRESULT
ret
;
LRESULT
msgRet
;
/* FIXME: need support for SMTO_BLOCK */
ret
=
MSG_SendMessage
(
hwnd
,
msg
,
wParam
,
lParam
,
timeout
,
SMSG_WIN32
|
SMSG_UNICODE
,
&
msgRet
);
*
resultp
=
(
DWORD
)
msgRet
;
return
ret
;
}
...
...
@@ -1671,7 +1693,7 @@ LRESULT WINAPI SendMessageTimeoutW( HWND hwnd, UINT msg, WPARAM wParam,
*/
void
WINAPI
WaitMessage
(
void
)
{
QUEUE_WaitBits
(
QS_ALLINPUT
);
QUEUE_WaitBits
(
QS_ALLINPUT
,
INFINITE
);
}
/***********************************************************************
...
...
This diff is collapsed.
Click to expand it.
windows/queue.c
+
31
−
65
View file @
bae5552a
...
...
@@ -611,21 +611,6 @@ MESSAGEQUEUE *QUEUE_GetSysQueue(void)
}
/***********************************************************************
* QUEUE_Wait
*/
static
void
QUEUE_Wait
(
DWORD
wait_mask
)
{
if
(
THREAD_IsWin16
(
THREAD_Current
()
)
)
WaitEvent16
(
0
);
else
{
TRACE
(
msg
,
"current task is 32-bit, calling SYNC_DoWait
\n
"
);
MsgWaitForMultipleObjects
(
0
,
NULL
,
FALSE
,
INFINITE
,
wait_mask
);
}
}
/***********************************************************************
* QUEUE_SetWakeBit
*
...
...
@@ -669,23 +654,31 @@ void QUEUE_ClearWakeBit( MESSAGEQUEUE *queue, WORD bit )
* QUEUE_WaitBits
*
* See "Windows Internals", p.447
*
* return values:
* 0 if exit with timeout
* 1 otherwise
*/
void
QUEUE_WaitBits
(
WORD
bits
)
int
QUEUE_WaitBits
(
WORD
bits
,
DWORD
timeout
)
{
MESSAGEQUEUE
*
queue
;
DWORD
curTime
=
0
;
TRACE
(
msg
,
"q %04x waiting for %04x
\n
"
,
GetFastQueue16
(),
bits
);
if
(
THREAD_IsWin16
(
THREAD_Current
()
)
&&
(
timeout
!=
INFINITE
)
)
curTime
=
GetTickCount
();
if
(
!
(
queue
=
(
MESSAGEQUEUE
*
)
QUEUE_Lock
(
GetFastQueue16
()
)))
return
0
;
for
(;;)
{
if
(
!
(
queue
=
(
MESSAGEQUEUE
*
)
QUEUE_Lock
(
GetFastQueue16
()
)))
return
;
if
(
queue
->
changeBits
&
bits
)
{
/* One of the bits is set; we can return */
queue
->
wakeMask
=
0
;
QUEUE_Unlock
(
queue
);
return
;
return
1
;
}
if
(
queue
->
wakeBits
&
QS_SENDMESSAGE
)
{
...
...
@@ -693,24 +686,40 @@ void QUEUE_WaitBits( WORD bits )
queue
->
wakeMask
=
0
;
QUEUE_ReceiveMessage
(
queue
);
QUEUE_Unlock
(
queue
);
continue
;
/* nested sm crux */
}
queue
->
wakeMask
=
bits
|
QS_SENDMESSAGE
;
if
(
queue
->
changeBits
&
bits
)
{
QUEUE_Unlock
(
queue
);
continue
;
}
TRACE
(
msg
,
"%04x) wakeMask is %04x, waiting
\n
"
,
queue
->
self
,
queue
->
wakeMask
);
QUEUE_Wait
(
queue
->
wakeMask
);
if
(
!
THREAD_IsWin16
(
THREAD_Current
()
)
)
{
/* win32 thread, use WaitForMultipleObjects */
MsgWaitForMultipleObjects
(
0
,
NULL
,
FALSE
,
timeout
,
queue
->
wakeMask
);
}
else
{
if
(
timeout
==
INFINITE
)
WaitEvent16
(
0
);
/* win 16 thread, use WaitEvent */
else
{
/* check for timeout, then give control to other tasks */
if
(
GetTickCount
()
-
curTime
>
timeout
)
{
QUEUE_Unlock
(
queue
);
return
0
;
/* exit with timeout */
}
Yield16
();
}
}
}
}
/***********************************************************************
...
...
@@ -919,54 +928,11 @@ void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue )
}
else
WARN
(
sendmsg
,
"
\t
rcm: bad hWnd
\n
"
);
/* sometimes when we got early reply, the receiver is in charge of
freeing up memory associated with smsg */
/* when there is an early reply the sender will not release smsg
before SMSG_RECEIVED is set */
if
(
smsg
->
flags
&
SMSG_EARLY_REPLY
)
{
/* remove smsg from the waiting list */
QUEUE_RemoveSMSG
(
queue
,
SM_WAITING_LIST
,
smsg
);
/* make thread safe when accessing SMSG_SENT_REPLY and
SMSG_RECEIVER_CLEANS_UP. Those fleags are used by both thread,
the sender and receiver, to find out which thread should released
smsg structure. The critical section of the sender queue is used. */
senderQ
=
(
MESSAGEQUEUE
*
)
QUEUE_Lock
(
smsg
->
hSrcQueue
);
/* synchronize with the sender */
if
(
senderQ
)
EnterCriticalSection
(
&
senderQ
->
cSection
);
/* tell the sender we're all done with smsg structure */
smsg
->
flags
|=
SMSG_RECEIVED
;
/* sender will set SMSG_RECEIVER_CLEANS_UP if it wants the
receiver to clean up smsg, it could only happens when there is
an early reply */
if
(
smsg
->
flags
&
SMSG_RECEIVER_CLEANS
)
{
TRACE
(
sendmsg
,
"Receiver cleans up!
\n
"
);
HeapFree
(
SystemHeap
,
0
,
smsg
);
}
/* release lock */
if
(
senderQ
)
{
LeaveCriticalSection
(
&
senderQ
->
cSection
);
QUEUE_Unlock
(
senderQ
);
}
}
else
{
/* no early reply, so do it now */
/* set SMSG_SENDING_REPLY flag to tell ReplyMessage16, it's not
an early reply */
smsg
->
flags
|=
SMSG_SENDING_REPLY
;
ReplyMessage
(
result
);
}
TRACE
(
sendmsg
,
"done!
\n
"
);
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment