Mercurial > foo_out_sdl
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #pragma once | |
| 2 | |
| 3 namespace foobar2000_io { | |
| 4 | |
| 5 PFC_DECLARE_EXCEPTION(exception_aborted,pfc::exception,"User abort"); | |
| 6 | |
| 7 typedef pfc::eventHandle_t abort_callback_event; | |
| 8 | |
| 9 #ifdef check | |
| 10 #undef check | |
| 11 #endif | |
| 12 //! This class is used to signal underlying worker code whether user has decided to abort a potentially time-consuming operation. \n | |
| 13 //! It is commonly required by all filesystem related or decoding-related operations. \n | |
| 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 | |
| 15 //! See abort_callback_impl for an implementation. | |
| 16 class NOVTABLE abort_callback | |
| 17 { | |
| 18 public: | |
| 19 //! Returns whether user has requested the operation to be aborted. | |
| 20 virtual bool is_aborting() const = 0; | |
| 21 | |
| 22 inline bool is_set() const {return is_aborting();} | |
| 23 | |
| 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 | |
| 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. | |
| 26 virtual abort_callback_event get_abort_event() const = 0; | |
| 27 | |
| 28 inline abort_callback_event get_handle() const {return get_abort_event();} | |
| 29 | |
| 30 //! Checks if user has requested the operation to be aborted, and throws exception_aborted if so. | |
| 31 void check() const; | |
| 32 | |
| 33 //! For compatibility with old code. Do not call. | |
| 34 inline void check_e() const {check();} | |
| 35 | |
| 36 | |
| 37 //! Sleeps p_timeout_seconds or less when aborted, throws exception_aborted on abort. | |
| 38 void sleep(double p_timeout_seconds) const; | |
| 39 //! Sleeps p_timeout_seconds or less when aborted, returns true when execution should continue, false when not. | |
| 40 bool sleep_ex(double p_timeout_seconds) const; | |
| 41 bool sleepNoThrow(double p_timeout_seconds) const { return sleep_ex(p_timeout_seconds); } | |
| 42 | |
| 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 | |
| 44 //! Throws exception_aborted if aborted. | |
| 45 bool waitForEvent( pfc::eventHandle_t evtHandle, double timeOut ) const; | |
| 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 | |
| 47 //! Throws exception_aborted if aborted. | |
| 48 bool waitForEvent(pfc::event& evt, double timeOut) const; | |
| 49 | |
| 50 //! Waits for an event. Returns once the event became signaled; throw exception_aborted if abort occurred first. | |
| 51 void waitForEvent(pfc::eventHandle_t evtHandle) const; | |
| 52 //! Waits for an event. Returns once the event became signaled; throw exception_aborted if abort occurred first. | |
| 53 void waitForEvent(pfc::event& evt) const; | |
| 54 | |
| 55 bool waitForEventNoThrow(pfc::eventHandle_t evt) const; | |
| 56 bool waitForEventNoThrow(pfc::event& evt) const; | |
| 57 | |
| 58 abort_callback( const abort_callback & ) = delete; | |
| 59 void operator=( const abort_callback & ) = delete; | |
| 60 protected: | |
| 61 abort_callback() {} | |
| 62 ~abort_callback() {} | |
| 63 }; | |
| 64 | |
| 65 | |
| 66 | |
| 67 //! Standard implementation of abort_callback interface. | |
| 68 class abort_callback_impl : public abort_callback { | |
| 69 public: | |
| 70 abort_callback_impl() {} | |
| 71 inline void abort() {set_state(true);} | |
| 72 inline void set() {set_state(true);} | |
| 73 inline void reset() {set_state(false);} | |
| 74 | |
| 75 void set_state(bool p_state) {m_aborting = p_state; m_event.set_state(p_state);} | |
| 76 | |
| 77 bool is_aborting() const override {return m_aborting;} | |
| 78 | |
| 79 abort_callback_event get_abort_event() const override {return m_event.get_handle();} | |
| 80 | |
| 81 private: | |
| 82 abort_callback_impl(const abort_callback_impl &) = delete; | |
| 83 const abort_callback_impl & operator=(const abort_callback_impl&) = delete; | |
| 84 | |
| 85 volatile bool m_aborting = false; | |
| 86 pfc::event m_event; | |
| 87 }; | |
| 88 | |
| 89 //! Alternate abort_callback implementation, supply your own event handle to signal abort. \n | |
| 90 //! Slightly less efficient (is_aborting() polls the event instead of reading a bool variable). | |
| 91 class abort_callback_usehandle : public abort_callback { | |
| 92 public: | |
| 93 abort_callback_usehandle( abort_callback_event handle ) : m_handle(handle) {} | |
| 94 | |
| 95 bool is_aborting() const override; | |
| 96 abort_callback_event get_abort_event() const override { return m_handle; } | |
| 97 protected: | |
| 98 const abort_callback_event m_handle; | |
| 99 }; | |
| 100 | |
| 101 class abort_callback_clone : public abort_callback_usehandle { | |
| 102 public: | |
| 103 abort_callback_clone(abort_callback_event handle) : abort_callback_usehandle(clone(handle)) {} | |
| 104 abort_callback_clone(abort_callback & arg) : abort_callback_usehandle(clone(arg.get_handle())) {} | |
| 105 ~abort_callback_clone() { close(m_handle); } | |
| 106 | |
| 107 static abort_callback_event clone(abort_callback_event); | |
| 108 static void close(abort_callback_event); | |
| 109 }; | |
| 110 | |
| 111 //! Dummy abort_callback that never gets aborted. \n | |
| 112 //! Note that there's no need to create instances of it, use shared fb2k::noAbort object instead. | |
| 113 class abort_callback_dummy : public abort_callback { | |
| 114 public: | |
| 115 bool is_aborting() const override { return false; } | |
| 116 | |
| 117 abort_callback_event get_abort_event() const override { return m_event;} | |
| 118 private: | |
| 119 const abort_callback_event m_event = GetInfiniteWaitEvent(); | |
| 120 }; | |
| 121 | |
| 122 } | |
| 123 typedef foobar2000_io::abort_callback_event fb2k_event_handle; | |
| 124 typedef foobar2000_io::abort_callback fb2k_event; | |
| 125 typedef foobar2000_io::abort_callback_impl fb2k_event_impl; | |
| 126 | |
| 127 using namespace foobar2000_io; | |
| 128 | |
| 129 #define FB2K_PFCv2_ABORTER_SCOPE( abortObj ) \ | |
| 130 (abortObj).check(); \ | |
| 131 PP::waitableReadRef_t aborterRef = {(abortObj).get_abort_event()}; \ | |
| 132 PP::aborter aborter_pfcv2( aborterRef ); \ | |
| 133 PP::aborterScope l_aborterScope( aborter_pfcv2 ); | |
| 134 | |
| 135 | |
| 136 namespace fb2k { | |
| 137 //! A shared abort_callback_dummy instance. \n | |
| 138 //! Use when some function requires an abort_callback& and you don't have one: somefunc(fb2k::noAbort); | |
| 139 extern abort_callback_dummy noAbort; | |
| 140 } |
