File Index
Symbol Index
#include "WindowsAsyncService.h"
namespace
vl
{
namespace
presentation
{
namespace
windows
{
using
namespace
collections
;
/*********************************************************************** WindowsAsyncService::TaskItem ***********************************************************************/
WindowsAsyncService
::
TaskItem
::
TaskItem
() :semaphore(
0
) { }
WindowsAsyncService
::
TaskItem
::
TaskItem
(
Semaphore
*
_semaphore
,
const
Func
<
void
()>&
_proc
) :semaphore(
_semaphore
) ,proc(
_proc
) { }
WindowsAsyncService
::
TaskItem
::
~
TaskItem
() { }
/*********************************************************************** WindowsAsyncService::DelayItem ***********************************************************************/
WindowsAsyncService
::
DelayItem
::
DelayItem
(
WindowsAsyncService
*
_service
,
const
Func
<
void
()>&
_proc
,
bool
_executeInMainThread
,
vint
milliseconds
) :service(
_service
) ,proc(
_proc
) ,status(
INativeDelay
::
Pending
) ,executeTime(
DateTime
::
LocalTime
().
Forward
(
milliseconds
)) ,executeInMainThread(
_executeInMainThread
) { }
WindowsAsyncService
::
DelayItem
::
~
DelayItem
() { }
INativeDelay
::
ExecuteStatus
WindowsAsyncService
::
DelayItem
::
GetStatus
() {
return
status
; }
bool
WindowsAsyncService
::
DelayItem
::
Delay
(
vint
milliseconds
) {
SPIN_LOCK(service->taskListLock)
if
(
bool
__scope_variable_flag__
=
true
)
for
(
const
SpinLock
::
Scope
&
scope
=
service
->
taskListLock
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
{
if
(
status
==
INativeDelay
::
Pending
) {
executeTime
=
DateTime
::
LocalTime
().
Forward
(
milliseconds
);
return
true
; } }
return
false
; }
bool
WindowsAsyncService
::
DelayItem
::
Cancel
() {
SPIN_LOCK(service->taskListLock)
if
(
bool
__scope_variable_flag__
=
true
)
for
(
const
SpinLock
::
Scope
&
scope
=
service
->
taskListLock
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
{
if
(
status
==
INativeDelay
::
Pending
) {
if
(
service
->
delayItems
.
Remove
(
this
)) {
status
=
INativeDelay
::
Canceled
;
return
true
; } } }
return
false
; }
/*********************************************************************** WindowsAsyncService ***********************************************************************/
WindowsAsyncService
::
WindowsAsyncService
() :mainThreadId(
Thread
::
GetCurrentThreadId
()) { }
WindowsAsyncService
::
~
WindowsAsyncService
() { }
void
WindowsAsyncService
::
ExecuteAsyncTasks
() {
DateTime
now
=
DateTime
::
LocalTime
();
Array
<
TaskItem
>
items
;
List
<
Ptr
<
DelayItem
>>
executableDelayItems
;
SPIN_LOCK(taskListLock)
if
(
bool
__scope_variable_flag__
=
true
)
for
(
const
SpinLock
::
Scope
&
scope
=
taskListLock
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
{
CopyFrom
(
items
,
taskItems
);
taskItems
.
RemoveRange
(
0
,
items
.
Count
());
for
(
vint
i
=
delayItems
.
Count
()-
1
;
i
>=
0
;
i
--) {
Ptr
<
DelayItem
>
item
=
delayItems
[
i
];
if
(
now
.
filetime
>=
item
-
>
executeTime
.
filetime
) {
item
-
>
status
=
INativeDelay
::
Executing
;
executableDelayItems
.
Add
(
item
);
delayItems
.
RemoveAt
(
i
); } } }
FOREACH(TaskItem, item, items)
if
(
bool
__scope_variable_flag__
=
true
)
for
(
const
::
vl
::
collections
::
ForEachIterator
<
TaskItem
>&
__foreach_iterator__
= ::
vl
::
collections
::
CreateForEachIterator
(
items
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
TaskItem
item
;
__foreach_iterator__
.
Next
(
item
);)
{
item
.
proc
(
);
if
(
item
.
semaphore
) {
item
.
semaphore
->
Release
(); } }
FOREACH(Ptr<DelayItem>, item, executableDelayItems)
if
(
bool
__scope_variable_flag__
=
true
)
for
(
const
::
vl
::
collections
::
ForEachIterator
<
Ptr
<
DelayItem
>>&
__foreach_iterator__
= ::
vl
::
collections
::
CreateForEachIterator
(
executableDelayItems
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
Ptr
<
DelayItem
>
item
;
__foreach_iterator__
.
Next
(
item
);)
{
if
(
item
-
>
executeInMainThread
) {
item
-
>
proc
(
);
item
-
>
status
=
INativeDelay
::
Executed
; }
else
{
InvokeAsync
([=]() {
item
-
>
proc
(
);
item
-
>
status
=
INativeDelay
::
Executed
; }); } } }
bool
WindowsAsyncService
::
IsInMainThread
(
INativeWindow
*
window
) {
return
Thread
::
GetCurrentThreadId
()==
mainThreadId
; }
void
WindowsAsyncService
::
InvokeAsync
(
const
Func
<
void
()>&
proc
) {
ThreadPoolLite
::
Queue
(
proc
); }
void
WindowsAsyncService
::
InvokeInMainThread
(
INativeWindow
*
window
,
const
Func
<
void
()>&
proc
) {
SPIN_LOCK(taskListLock)
if
(
bool
__scope_variable_flag__
=
true
)
for
(
const
SpinLock
::
Scope
&
scope
=
taskListLock
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
{
TaskItem
item
(
0
,
proc
);
taskItems
.
Add
(
item
); } }
bool
WindowsAsyncService
::
InvokeInMainThreadAndWait
(
INativeWindow
*
window
,
const
Func
<
void
()>&
proc
,
vint
milliseconds
) {
Semaphore
semaphore
;
semaphore
.
Create
(
0
,
1
);
SPIN_LOCK(taskListLock)
if
(
bool
__scope_variable_flag__
=
true
)
for
(
const
SpinLock
::
Scope
&
scope
=
taskListLock
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
{
TaskItem
item
(&
semaphore
,
proc
);
taskItems
.
Add
(
item
); }
if
(
milliseconds
<
0
) {
return
semaphore
.
Wait
(); }
else
{
return
semaphore
.
WaitForTime
(
milliseconds
); } }
Ptr
<
INativeDelay
>
WindowsAsyncService
::
DelayExecute
(
const
Func
<
void
()>&
proc
,
vint
milliseconds
) {
Ptr
<
DelayItem
>
delay
;
SPIN_LOCK(taskListLock)
if
(
bool
__scope_variable_flag__
=
true
)
for
(
const
SpinLock
::
Scope
&
scope
=
taskListLock
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
{
delay
=
new
DelayItem
(
this
,
proc
,
false
,
milliseconds
);
delayItems
.
Add
(
delay
); }
return
delay
; }
Ptr
<
INativeDelay
>
WindowsAsyncService
::
DelayExecuteInMainThread
(
const
Func
<
void
()>&
proc
,
vint
milliseconds
) {
Ptr
<
DelayItem
>
delay
;
SPIN_LOCK(taskListLock)
if
(
bool
__scope_variable_flag__
=
true
)
for
(
const
SpinLock
::
Scope
&
scope
=
taskListLock
;
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
{
delay
=
new
DelayItem
(
this
,
proc
,
true
,
milliseconds
);
delayItems
.
Add
(
delay
); }
return
delay
; } } } }