annotate foosdk/sdk/foobar2000/SDK/abort_callback.h @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #pragma once
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 namespace foobar2000_io {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 PFC_DECLARE_EXCEPTION(exception_aborted,pfc::exception,"User abort");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 typedef pfc::eventHandle_t abort_callback_event;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 #ifdef check
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 #undef check
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 //! This class is used to signal underlying worker code whether user has decided to abort a potentially time-consuming operation. \n
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 //! It is commonly required by all filesystem related or decoding-related operations. \n
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 //! Code that receives an abort_callback object should periodically check it and abort any operations being performed if it is signaled, typically throwing exception_aborted. \n
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 //! See abort_callback_impl for an implementation.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 class NOVTABLE abort_callback
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 //! Returns whether user has requested the operation to be aborted.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 virtual bool is_aborting() const = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 inline bool is_set() const {return is_aborting();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 //! Retrieves event object that can be used with some OS calls. The even object becomes signaled when abort is triggered. On win32, this is equivalent to win32 event handle (see: CreateEvent). \n
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 //! You must not close this handle or call any methods that change this handle's state (SetEvent() or ResetEvent()), you can only wait for it.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 virtual abort_callback_event get_abort_event() const = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 inline abort_callback_event get_handle() const {return get_abort_event();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 //! Checks if user has requested the operation to be aborted, and throws exception_aborted if so.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 void check() const;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 //! For compatibility with old code. Do not call.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 inline void check_e() const {check();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 //! Sleeps p_timeout_seconds or less when aborted, throws exception_aborted on abort.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 void sleep(double p_timeout_seconds) const;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 //! Sleeps p_timeout_seconds or less when aborted, returns true when execution should continue, false when not.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 bool sleep_ex(double p_timeout_seconds) const;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 bool sleepNoThrow(double p_timeout_seconds) const { return sleep_ex(p_timeout_seconds); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 //! Waits for an event. Returns true if event is now signaled, false if the specified period has elapsed and the event did not become signaled. \n
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 //! Throws exception_aborted if aborted.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 bool waitForEvent( pfc::eventHandle_t evtHandle, double timeOut ) const;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 //! Waits for an event. Returns true if event is now signaled, false if the specified period has elapsed and the event did not become signaled. \n
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 //! Throws exception_aborted if aborted.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 bool waitForEvent(pfc::event& evt, double timeOut) const;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 //! Waits for an event. Returns once the event became signaled; throw exception_aborted if abort occurred first.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 void waitForEvent(pfc::eventHandle_t evtHandle) const;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 //! Waits for an event. Returns once the event became signaled; throw exception_aborted if abort occurred first.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 void waitForEvent(pfc::event& evt) const;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 bool waitForEventNoThrow(pfc::eventHandle_t evt) const;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 bool waitForEventNoThrow(pfc::event& evt) const;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 abort_callback( const abort_callback & ) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 void operator=( const abort_callback & ) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 protected:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 abort_callback() {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 ~abort_callback() {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 //! Standard implementation of abort_callback interface.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 class abort_callback_impl : public abort_callback {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 abort_callback_impl() {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 inline void abort() {set_state(true);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 inline void set() {set_state(true);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 inline void reset() {set_state(false);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 void set_state(bool p_state) {m_aborting = p_state; m_event.set_state(p_state);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 bool is_aborting() const override {return m_aborting;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 abort_callback_event get_abort_event() const override {return m_event.get_handle();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 abort_callback_impl(const abort_callback_impl &) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 const abort_callback_impl & operator=(const abort_callback_impl&) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 volatile bool m_aborting = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 pfc::event m_event;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 //! Alternate abort_callback implementation, supply your own event handle to signal abort. \n
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 //! Slightly less efficient (is_aborting() polls the event instead of reading a bool variable).
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 class abort_callback_usehandle : public abort_callback {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 abort_callback_usehandle( abort_callback_event handle ) : m_handle(handle) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 bool is_aborting() const override;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 abort_callback_event get_abort_event() const override { return m_handle; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 protected:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 const abort_callback_event m_handle;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 class abort_callback_clone : public abort_callback_usehandle {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 abort_callback_clone(abort_callback_event handle) : abort_callback_usehandle(clone(handle)) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 abort_callback_clone(abort_callback & arg) : abort_callback_usehandle(clone(arg.get_handle())) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 ~abort_callback_clone() { close(m_handle); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 static abort_callback_event clone(abort_callback_event);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 static void close(abort_callback_event);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 //! Dummy abort_callback that never gets aborted. \n
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 //! Note that there's no need to create instances of it, use shared fb2k::noAbort object instead.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 class abort_callback_dummy : public abort_callback {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 bool is_aborting() const override { return false; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 abort_callback_event get_abort_event() const override { return m_event;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 const abort_callback_event m_event = GetInfiniteWaitEvent();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 typedef foobar2000_io::abort_callback_event fb2k_event_handle;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 typedef foobar2000_io::abort_callback fb2k_event;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 typedef foobar2000_io::abort_callback_impl fb2k_event_impl;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 using namespace foobar2000_io;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 #define FB2K_PFCv2_ABORTER_SCOPE( abortObj ) \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 (abortObj).check(); \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 PP::waitableReadRef_t aborterRef = {(abortObj).get_abort_event()}; \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 PP::aborter aborter_pfcv2( aborterRef ); \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 PP::aborterScope l_aborterScope( aborter_pfcv2 );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 namespace fb2k {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 //! A shared abort_callback_dummy instance. \n
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 //! Use when some function requires an abort_callback& and you don't have one: somefunc(fb2k::noAbort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139 extern abort_callback_dummy noAbort;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 }