acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
task.h
1#pragma once
2
3
4//#include "acme/operating_system/error_code.h"
5//#include "acme/prototype/prototype/_u32hash.h"
6//#include "acme/prototype/prototype/function.h"
7//#include "acme/prototype/prototype/object.h"
8//#include "acme/prototype/collection/procedure_array.h"
9#include "acme/parallelization/counter.h"
10#include "acme/constant/happening.h"
11#include "acme/handler/handler.h"
12#include "acme/handler/source.h"
13#include "acme/parallelization/synchronization_array.h"
14#include "acme/parallelization/types.h"
15#include "acme/platform/implementable.h"
16#include "acme/platform/timer.h"
17#include "acme/prototype/data/property_container.h"
18#include "acme/prototype/collection/block_array.h"
19#include "acme/prototype/collection/comparable_eq_list.h"
20#include "acme/prototype/collection/procedure_array.h"
21
22
23#ifndef WINDOWS
24
25/*
26 * Queue status flags for GetQueueStatus() and MsgWaitForMultipleObjects()
27 */
28#define QS_KEY 0x0001
29#define QS_MOUSEMOVE 0x0002
30#define QS_MOUSEBUTTON 0x0004
31#define QS_POSTMESSAGE 0x0008
32#define QS_TIMER 0x0010
33#define QS_PAINT 0x0020
34#define QS_SENDMESSAGE 0x0040
35#define QS_HOTKEY 0x0080
36#define QS_ALLPOSTMESSAGE 0x0100
37
38#if(_WIN32_WINNT >= 0x0501)
39#define QS_RAWINPUT 0x0400
40#endif /* _WIN32_WINNT >= 0x0501 */
41
42#if(_WIN32_WINNT >= 0x0602)
43#define QS_TOUCH 0x0800
44#define QS_POINTER 0x1000
45
46#endif /* _WIN32_WINNT >= 0x0602 */
47
48
49#define QS_MOUSE (QS_MOUSEMOVE | \
50 QS_MOUSEBUTTON)
51
52#if (_WIN32_WINNT >= 0x602)
53#define QS_INPUT (QS_MOUSE | \
54 QS_KEY | \
55 QS_RAWINPUT | \
56 QS_TOUCH | \
57 QS_POINTER)
58
59#else
60#if (_WIN32_WINNT >= 0x0501)
61#define QS_INPUT (QS_MOUSE | \
62 QS_KEY | \
63 QS_RAWINPUT)
64#else
65#define QS_INPUT (QS_MOUSE | \
66 QS_KEY)
67#endif // (_WIN32_WINNT >= 0x0501)
68#endif
69
70#define QS_ALLEVENTS (QS_INPUT | \
71 QS_POSTMESSAGE | \
72 QS_TIMER | \
73 QS_PAINT | \
74 QS_HOTKEY)
75
76#define QS_ALLINPUT (QS_INPUT | \
77 QS_POSTMESSAGE | \
78 QS_TIMER | \
79 QS_PAINT | \
80 QS_HOTKEY | \
81 QS_SENDMESSAGE)
82
83#endif
84
85DECLARE_C_FLAG(e_happening, enum_happening);
86
87
88class locale;
89
90typedef pointer_array < ::matter > object_array;
91//typedef map_base < ::task_index, ::pointer<task >>task_map;
92//typedef map_base < task *, ::task_index > task_id_map;
93using procedure_list_base = ::list_base < procedure >;
94
95//::task_index task_index(itask itask);
96CLASS_DECL_ACME ::task_index current_task_index();
97
98
100
101
102using waiting_call_stack = ::comparable_eq_list_base < ::waiting_call_base * >;
103
104
105// TTThomas loves handlers. Jeg elsker dig Thomas.
106class task_handler;
107
108
109class CLASS_DECL_ACME task :
110 virtual public ::object,
111 virtual public ::acme::implementable,
112 virtual public ::handler::handler,
113 virtual public ::timer_handler,
114 virtual public ::platform::tracer,
115 virtual public ::source,
116 virtual public ::data::property_container
117{
118public:
119
120
121 class ::time m_timeLastFinishingReport;
122 //Creatable(task);
123
124 //bool m_bAutoRelease : 1;
125 union
126 {
127
128
129 struct
130 {
131
132
133 bool m_bAvoidProcedureFork : 1;
134 //bool m_bIsRunning : 1;
135 bool m_bIsPredicate : 1; // Is helper thread (as opposite to a "main" thread)
136#ifdef WINDOWS
137 bool m_bCoInitialize : 1;
138 bool m_bCoInitialized : 1;
139 bool m_bCoInitializeMultithreaded : 1;
140#endif
141 bool m_bMessageThread : 1;
142 bool m_bMessageThread2 : 1;
143 bool m_bHandleRequest : 1;
144 bool m_bHandleProcedure : 1;
145 bool m_bHandleHappening : 1;
146 bool m_bTaskToolsForIncreasedFps : 1;
147 bool m_bHandlingMessages : 1;
148#ifdef PARALLELIZATION_PTHREAD
149 bool m_bJoinable : 1;
150#endif
151 bool m_bRunMainLoop : 1;
152 bool m_bAutoStartOnTimerAdded :1;
153 bool m_bBranchCall : 1;
154
155 };
156
157
158 ::u64 m_hnTaskFlag;
159
160
161 };
162
163 ::u64 m_uThreadAffinityMask;
164
165#if defined(WINDOWS)
166
167 ::pointer<::exception_translator> m_pexceptiontranslator;
168
169#endif
170
171::i64 m_iTaskObjectSerialId;
172 class ::time m_timeSample;
173
174 class finishing :
175 virtual public ::particle
176 {
177 public:
178
179
180
181
182
183 class ::time m_timeFinishing;
184
185 finishing()
186 {
187 ping();
188 }
189 ~finishing()
190 {
191
192 }
193
194 bool has_finishing_timed_out(const class ::time & timeTimeout)
195 {
196
197 if(m_timeFinishing.elapsed() > timeTimeout)
198 {
199
200 return true;
201
202 }
203
204 return false;
205
206 }
207
208 void ping()
209 {
210
211 m_timeFinishing.Now();
212
213 }
214
215 };
216 ::pointer < finishing > m_pfinishing;
217 //bool m_bDetectedHasFinishingFlag = false;
218
219 //::pointer<::manual_reset_happening> m_pmanualresethappeningNewProcedurePosted;
220
221 ::synchronization_array m_synchronizationaMainLoop;
222 ::task_index m_taskindex;
223 htask m_htask;
224 itask m_itask;
225 string m_strTaskName;
226 string m_strTaskTag;
227
228
229 ::pointer < ::acme::user::interaction > m_pacmeuserinteractionMain; // Main user interaction (usually same psystem->m_puiMain)
230 ::pointer < ::acme::user::interaction > m_pacmeuserinteractionActive; // Active user interaction (may not be m_puiMain)
231
232 ::particle_array m_particleaHold;
233 ::pointer<manual_reset_happening> m_phappeningInitialization;
234
235 ::procedure m_procedure;
236 ::pointer<manual_reset_happening> m_pevSleep;
237 ::pointer<manual_reset_happening> m_phappeningFinished2;
238 //::pointer<manual_reset_happening> m_pmanualresethappeningHappening;
239 ::comparable_array<e_happening> m_ehappeninga;
240
241 ::string_map < ::procedure > m_mapDoHappenings;
242#ifdef WINDOWS
243 error_code m_errorcodeHresultCoInitialize;
244#endif
245
246#ifdef _DEBUG
247 char_pointer m_pszDebug;
248#endif
249 ::pointer < ::parallelization::counter > m_pcounter;
250 ::task_pointer m_ptask;
251
252
253 // ::procedure m_procedureNext;
254
255
256 ::procedure_array m_procedurea2;
257 ::procedure_list_base m_procedurelistHandling;
258
259 ::pointer < ::locale > m_plocale;
260
261 class ::time m_timeLastPing;
262 class ::time m_timePingTimeout;
263 //::procedure m_procedureTaskEnded;
264 class ::time m_timeLastPostedProcedureStart;
265 class ::time m_timeDefaultPostedProcedureTimeout;
266 class ::time m_timePostedProcedureTimeout;
267
268
269
270 ::waiting_call_stack m_waitingcallstack;
271
272 ::i32 m_iExitCode;
273
274
275
277 {
278 public:
279
280
281 const ::subparticle *m_psubparticleContext;
282 ::subparticle *m_psubparticleSynchronization;
283 const_char_pointer m_pszFile;
284 ::i32 m_iLine;
285 };
286
287
289 m_synchronouslockdescriptiona;
290private:
291 critical_section m_criticalsectionMsgTranslator;
292#if defined(WINDOWS_DESKTOP)
293 ::comparable_array<::function<bool(MSG *)>> m_msgtranslatora;
294#endif
295 public:
296
297 task();
298 ~task() override;
299
300
301 void on_initialize_particle() override;
302
303 void on_new_main_loop_happening_creation() override;
304
305#if defined(WINDOWS_DESKTOP)
306 virtual void add_msg_translator(::function<bool(MSG *)> msgtranslator);
307 virtual void erase_msg_translator(::function<bool(MSG *)> msgtranslator);
308
309 virtual bool msg_translator_handlers(MSG *pmsg);
310#endif
311 //virtual void on_pre_run_task();
312
313
314 //void update_new_main_loop_happening() override;
315 //bool has_main_loop_happening() override;
316
317#ifdef WINDOWS
318
319 virtual bool _defer_co_initialize_ex(bool bMultiThread);
320
321#endif
322
323
324 virtual void on_single_lock_lock(::subparticle *psubparticleSynchronization,
325 const ::subparticle *psubparticleContext, const_char_pointer pszFile,
326 ::i32 iLine);
327 virtual void on_single_lock_unlock(::subparticle *psubparticleSynchronization);
328
329
330 virtual void __priority_and_affinity();
331 void set_finish() override;
332 //virtual void __os_initialize();
333 // virtual void __os_thread_start();
334 virtual void set_task();
335 //virtual void __os_finalize();
336 virtual void unset_task();
337
338 //void task_osinit() override;
339 //void task_osterm() override;
340
341 bool is_locked() const override;
342
343 bool has_main_loop_happening() override;
344 virtual bool _has_main_loop_happening_unlocked();
345
346 //virtual bool os_on_init_task();
347 //virtual void os_on_term_task();
348 //virtual ::manual_reset_happening * new_main_loop_happening();
349
350 //virtual ::manual_reset_happening* new_happening();
351
352 void on_start_timers_handling_hint() override;
353 void on_stop_timers_handling_hint() override;
354
355
356 virtual bool pick_next_posted_procedure();
357
358 virtual e_happening pick_happening();
359
360 string get_tag() const override;
361 string task_get_name() const;
362
363
364 ::task * get_task() override;
365 const_char_pointer get_task_tag() override;
366
367
368 virtual ::acme::user::interaction * get_active_user_interaction();
369 virtual void set_active_user_interaction(::acme::user::interaction * pacmeuserinteraction);
370
371 void add_task(::object* pobjectTask) override;
372
373 virtual bool is_current_task() const;
374 //virtual object * calc_parent_thread();
375
376 virtual void post_request(::request* prequest) override;
377
378 virtual bool task_set_name(const ::scoped_string & scopedstrName);
379
380#ifdef WINDOWS
381
382 static ::u32 WINDOWS_API s_os_task(void* p);
383
384#else
385
386 static void* s_os_task(void* p);
387
388#endif
389
390
391 bool is_task_set2() const override;
392 //virtual void register_task();
393 //virtual void unregister_task();
394
395
396 virtual ::locale * locale();
397
398 //virtual bool has_dependant_tasks() const;
399
400 //virtual void add_notify(::matter* pmatter);
401 //virtual void erase_notify(::matter* pmatter);
402
403 void post(const ::procedure & procedure) override;
404 void send(const ::procedure & procedure) override;
405
406
407 //void _post(::subparticle * p) override;
408 //void _send(::subparticle * p) override;
409
410 //virtual v do_synchronously(sequence * psequence);
411
412
413 virtual void handle_posted_procedures();
414
415 virtual void task_caller_on_init();
416
417 virtual bool on_get_task_name(string & strThreadName);
418
419 virtual void set_happened(e_happening ehappening);
420
421 virtual bool on_happening(e_happening ehappening);
422
423
424 virtual ::i32 __task_main();
425 virtual void __task_init();
426 //virtual void __task_main(::procedure & procedureTaskEnded);
427 virtual void __task_term();
428
429
430 virtual void call_init_task();
431
432 void init_task() override;
433 void term_task() override;
434
435 //virtual void do_task() override;
436 //virtual void on_task() override;
437
438 //virtual bool do_tasks();
439 //virtual bool defer_pump_message();
440
441
442 virtual bool has_message() const;
443
444 virtual void on_before_branch();
445
446 using ::object::branch;
447
448 virtual void branch(enum_parallelization eparallelization = e_parallelization_asynchronous, const create_task_attributes_t& createtaskattributes = {});
449
450 virtual void branch_synchronously(const create_task_attributes_t & createtaskattributes = {});
451
452 virtual bool task_sleep(const class time & timeWait);
453
454 //virtual void on_before_destroy_task();
455
456
457 //template < typename METHOD >
458 //inline static ::task_pointer __task(METHOD method)
459 //{
460
461 // auto pmethod = method(method);
462
463 // auto ptask = start(pmethod);
464
465 // return ptask;
466
467 //}
468
469
470// static ::task_pointer launch(
471// ::matter* pmatter,
472// ::enum_priority epriority = e_priority_normal,
473// ::u32 nStackSize = 0,
474// ::u32 dwCreateFlags = 0);
475
476
477 //virtual ::property_object * thread_parent();
478
479 //void __task_init() override;
480 //void __task_term() override;
481
482
483
484 virtual bool is_thread_class() const override;
485 bool should_run() const override;
486
487 bool is_ready_to_quit() const override;
488
489 //virtual bool task_active() const;
490 //virtual bool is_running() const override;
491
492 //bool set_children_to_finish_and_check_them_finished() override;
493
494 bool has_child_task() const override;
495
496 void set_child_tasks_to_finish() override;
497
498 virtual void update_task_ready_to_quit();
499
500 //virtual void on_task_quit();
501
502 virtual void kick_thread();
503
504 virtual ::i32 call_main();
505 virtual void main();
506
507 void run() override;
508
509 virtual void run_main_loop();
510
511
512 virtual void run_loop();
513 virtual void run_loop1(::task *ptask);
514 virtual void run_loop2(::task *ptask);
515
516 virtual void run_default_loop1();
517
518 virtual bool task_run(const class ::time & time = 0_s);
519
523 virtual bool task_wait(const class ::time & timeRemaining = 0_s);
524
525 virtual bool task_iteration();
526
527 virtual bool handle_messages();
528
529 virtual void stop_task();
530
531
532 void destroy() override;
533
534
535 //virtual bool task_set_name(const ::scoped_string & scopedstrThreadName);
536
537 //virtual bool is_predicate() const { return !m_pobject || m_pobject.get() == this; }
538
539 //virtual void set_thread_run(bool bRun = true);
540
541 //virtual void finish() override;
542
543 //virtual void set_current_handles();
544
545 void kick_idle() override;
546
547 bool is_branch_current() const override;
548
549
550 virtual void synchronous_procedure(bool bAtAnotherThread, const procedure & procedure, const class ::time & timeTimeout = 0_s);
551
552
553};
554
555
556using task_array = pointer_array < task >;
557
558
559
560
561
562
563inline ::payload & task_property(const ::atom & atom) { return ::get_task()->payload(atom); }
564
565
566
567
568//
569//class CLASS_DECL_ACME thread_local_particle :
570// virtual public ::particle
571//{
572//public:
573//
574//
575// thread_local_particle * m_pthreadlocalparticleNext;
576//
577//
578// thread_local_particle();
579// ~thread_local_particle() override;
580//
581//
582//};
583//
584//
585//template < typename TYPE >
586//class thread_local_pointer :
587// public ::thread_local_particle,
588// public pointer <TYPE >
589//{
590//public:
591//
592//
593// using pointer < TYPE >::pointer;
594//
595//
596// using pointer < TYPE >::operator = ;
597//
598//
599//};
600
601
602
603
604
605
606typedef string GET_TASK_NAME(::task * ptask);
607using LPFN_GET_TASK_NAME = GET_TASK_NAME *;
608
609
610CLASS_DECL_ACME string get_task_name(htask htask);
611
612CLASS_DECL_ACME void set_get_task_name(LPFN_GET_TASK_NAME);
613
614CLASS_DECL_ACME void task_set_name(const ::scoped_string & scopedstrName);
615CLASS_DECL_ACME void task_set_name(htask htask, const ::scoped_string & scopedstrName);
616
617
618CLASS_DECL_ACME string task_get_name();
619CLASS_DECL_ACME string task_get_name(htask htask);
620
621
622CLASS_DECL_ACME void thread_name_abbreviate(string & strName, ::i32 len);
623
624
625//CLASS_DECL_ACME ::task * _get_task();
626
627
628CLASS_DECL_ACME ::task * get_task();
629
630
631//CLASS_DECL_ACME::task* get_task();
632CLASS_DECL_ACME void set_task(task * ptask);
633
634CLASS_DECL_ACME string get_task_name(::task * ptask);
635
636CLASS_DECL_ACME string current_task_name();
637
638
639template<typename THREAD_POINTER>
641
642
643using task_pointer = ::pointer<::task>;
644
645
646class task_pool;
647
648
649CLASS_DECL_ACME void predicate_preempt(const class ::time & time, const ::function < bool() > & function);
650
651
652CLASS_DECL_ACME void task_release();
653CLASS_DECL_ACME void task_iteration();
654CLASS_DECL_ACME void task_run(const class ::time & time = 0_s);
655
656
657
Definition task.h:640
Definition implementable.h:14
Definition interaction.h:50
Definition atom.h:237
Definition block_array.h:7
Definition critical_section.h:9
Definition property_container.h:17
Definition error_code.h:22
Definition _template_forward_declaration.h:297
Definition handler.h:22
Definition types.h:47
Definition types.h:93
Definition locale.h:21
virtual void destroy() override
Definition bbb_context_object.cpp:242
Definition tracer.h:19
Definition synchronization_array.h:54
Definition task_handler.h:9
Definition pool.h:9
Definition task.h:117
virtual void branch(enum_parallelization eparallelization=e_parallelization_asynchronous, const create_task_attributes_t &createtaskattributes={})
Definition task.cpp:2929
Definition aaa_time.h:13
Definition waiting_call.h:10
Definition create_task_attributes.h:12