Tutorials to .com

Tutorials to .com » Software » Asm » WIN32 compilation: 16. Event object

WIN32 compilation: 16. Event object

Print View , by: iSee ,Total views: 9 ,Word Count: 1819 ,Date: Fri, 8 May 2009 Time: 10:29 AM

16th event object lesson


This lesson we will learn from the incident to the object and how to multi-threaded programming in how to use the synchronization object.

Theory:

We demonstrated a lesson in how to use information in different WINDOWS communicate between threads. The other two, namely: the use of global variables and the event object will be explained in this lesson.
Event object like a switch: it is only two states --- OFF. When an event is "on" state, we call "signal" Otherwise known as the "No Signal." You can thread the implementation of a function to create an event object, and then observe its state, if it is "no signal" let the thread sleep, so that the thread occupied less CPU time.
Event object have the function as follows:

CreateEvent proto lpEventAttributes: DWORD, \
bManualReset: DWORD, \
bInitialState: DWORD, \
lpName: DWORD

lpEventAttribute -> If it is NULL value, resulting in the event object have the default security attributes.
bManualReset -> If you want to let each WaitForSingleObject call WINDOWS automatically for you to state the case back to "no signal" state, the parameters must be set to FALSE, otherwise, you must call each function to clear the incident ResetEvent signal.
bInitialState -> just have the status of the incident object. TRUE if the set is a "signal", otherwise it is "no signal."
lpName -> event object's name. You may use OpenEvent function.

CreateEvent call, if successful, will return to the subject of a new generation of the handle, otherwise return NULL.
There are two API functions used to modify the state of the signal event object: SetEvent and ResetEvent. The former event object is set to "signal" state, while the latter is just the opposite.
Generated in the event object, you must call to make WaitForSingleObject thread into the wait state, the function syntax is as follows:

WaitForSingleObject proto hObject: DWORD, dwTimeout: DWORD

hObject -> point to synchronization object. Event object is a synchronization object.
dwTimeout -> wait for synchronization objects into a "signal" before the waiting time, in milliseconds. When the waiting time of no more than the value of signal synchronization object is still in "no signal" state, no longer waiting for the thread, WaitForSingleObject function will return. If you want to have to wait for the thread, please set the parameter to INFINITE (equivalent to the value 0xffffffff).

Examples:

The following example shows a window, when the user selects the menu item "run thread", the thread count of the beginning of a simple operation. After the end of a pop-up dialog box to notify the user. Count throughout the period, you can choose menu item "stop thread" to terminate the thread at any time.

.386
. model flat, stdcall
option casemap: none
WinMain proto: DWORD,: DWORD,: DWORD,: DWORD
include \ masm32 \ include \ windows.inc
include \ masm32 \ include \ user32.inc
include \ masm32 \ include \ kernel32.inc
includelib \ masm32 \ lib \ user32.lib
includelib \ masm32 \ lib \ kernel32.lib

. const
IDM_START_THREAD equ 1
IDM_STOP_THREAD equ 2
IDM_EXIT equ 3
WM_FINISH equ WM_USER +100 h

. data
ClassName db "Win32ASMEventClass", 0
AppName db "Win32 asm Event Example", 0
MenuName db "FirstMenu", 0
SuccessString db "The calculation is completed!", 0
StopString db "The thread is stopped", 0
EventStop BOOL FALSE

. data?
hInstance HINSTANCE?
CommandLine LPSTR?
hwnd HANDLE?
hMenu HANDLE?
ThreadID DWORD?
ExitCode DWORD?
hEventStart HANDLE?

. code
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke GetCommandLine
mov CommandLine, eax
invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT
invoke ExitProcess, eax

WinMain proc hInst: HINSTANCE, hPrevInst: HINSTANCE, CmdLine: LPSTR, CmdShow: DWORD
LOCAL wc: WNDCLASSEX
LOCAL msg: MSG
mov wc.cbSize, SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
push hInst
pop wc.hInstance
mov wc.hbrBackground, COLOR_WINDOW +1
mov wc.lpszMenuName, OFFSET MenuName
mov wc.lpszClassName, OFFSET ClassName
invoke LoadIcon, NULL, IDI_APPLICATION
mov wc.hIcon, eax
mov wc.hIconSm, eax
invoke LoadCursor, NULL, IDC_ARROW
mov wc.hCursor, eax
invoke RegisterClassEx, addr wc
invoke CreateWindowEx, WS_EX_CLIENTEDGE, ADDR ClassName, \
ADDR AppName, \
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, \
CW_USEDEFAULT, 300,200, NULL, NULL, \
hInst, NULL
mov hwnd, eax
invoke ShowWindow, hwnd, SW_SHOWNORMAL
invoke UpdateWindow, hwnd
invoke GetMenu, hwnd
mov hMenu, eax
. WHILE TRUE
invoke GetMessage, ADDR msg, NULL, 0,0
. BREAK. IF (! Eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
. ENDW
mov eax, msg.wParam
ret
WinMain endp

WndProc proc hWnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM
. IF uMsg == WM_CREATE
invoke CreateEvent, NULL, FALSE, FALSE, NULL
mov hEventStart, eax
mov eax, OFFSET ThreadProc
invoke CreateThread, NULL, NULL, eax, \
NULL, 0, \
ADDR ThreadID
invoke CloseHandle, eax
. ELSEIF uMsg == WM_DESTROY
invoke PostQuitMessage, NULL
. ELSEIF uMsg == WM_COMMAND
mov eax, wParam
. if lParam == 0
. if ax == IDM_START_THREAD
invoke SetEvent, hEventStart
invoke EnableMenuItem, hMenu, IDM_START_THREAD, MF_GRAYED
invoke EnableMenuItem, hMenu, IDM_STOP_THREAD, MF_ENABLED
. elseif ax == IDM_STOP_THREAD
mov EventStop, TRUE
invoke EnableMenuItem, hMenu, IDM_START_THREAD, MF_ENABLED
invoke EnableMenuItem, hMenu, IDM_STOP_THREAD, MF_GRAYED
. else
invoke DestroyWindow, hWnd
. endif
. endif
. ELSEIF uMsg == WM_FINISH
invoke MessageBox, NULL, ADDR SuccessString, ADDR AppName, MB_OK
. ELSE
invoke DefWindowProc, hWnd, uMsg, wParam, lParam
ret
. ENDIF
xor eax, eax
ret
WndProc endp

ThreadProc PROC USES ecx Param: DWORD
invoke WaitForSingleObject, hEventStart, INFINITE
mov ecx, 600000000
. WHILE ecx! = 0
. if EventStop! = TRUE
add eax, eax
dec ecx
. else
invoke MessageBox, hwnd, ADDR StopString, ADDR AppName, MB_OK
mov EventStop, FALSE
jmp ThreadProc
. endif
. ENDW
invoke PostMessage, hwnd, WM_FINISH, NULL, NULL
invoke EnableMenuItem, hMenu, IDM_START_THREAD, MF_ENABLED
invoke EnableMenuItem, hMenu, IDM_STOP_THREAD, MF_GRAYED
jmp ThreadProc
ret
ThreadProc ENDP
end start

Analysis:

This case, another demonstration of our skills:

. IF uMsg == WM_CREATE
invoke CreateEvent, NULL, FALSE, FALSE, NULL
mov hEventStart, eax
mov eax, OFFSET ThreadProc
invoke CreateThread, NULL, NULL, eax, \
NULL, 0, \
ADDR ThreadID
invoke CloseHandle, eax

In WM_CREATE message processing, we generate the events and create a thread synchronization object. We set the value of the related object when the synchronization so that a "No Signal" state but also in the WaitForSingleObject call automatically after a state event object is set to "No Signal." Then we create a thread. Thread started immediately after the code is blocked:

ThreadProc PROC USES ecx Param: DWORD
invoke WaitForSingleObject, hEventStart, INFINITE
mov ecx, 600000000

You can see the implementation of thread-body code is the first call WaitForSingleObject function, which allows threads to wait for obstructive events and has been the object into a "signal." That is to say, we started to let the thread into the sleep state. When the user selects the menu item "run thread", we have state of the event object into a "signal":

. if ax == IDM_START_THREAD
invoke SetEvent, hEventStart

Synchronization function allows SetEvent object into a "signal" state, then the next thread to be run-time slot, WaitForSingleObject function returns, thread the remaining code can be implemented. When the user selects the menu item "stop thread", we EventStop the global variable is set to TRUE.

. if EventStop == FALSE
add eax, eax
dec ecx
. else
invoke MessageBox, hwnd, ADDR StopString, ADDR AppName, MB_OK
mov EventStop, FALSE
jmp ThreadProc
. endif

This thread was the end of counting, and then Jump to the re-implementation of the local WaitForSingleObject function. Note: we do not have to manually clear the event object's signal, because the CreateEvent function to call when the value of the parameter set bManualReset a FALSE.



Assembly Language Tutorial Articles


Can't Find What You're Looking For?


Rating: Not yet rated

Comments

No comments posted.