X-Git-Url: https://git.mdrn.pl/wl-app.git/blobdiff_plain/53b27422d140022594fc241cca91c3183be57bca..48b2fe9f7c2dc3d9aeaaa6dbfb27c7da4f3235ff:/iOS/Pods/Realm/include/core/realm/util/interprocess_condvar.hpp diff --git a/iOS/Pods/Realm/include/core/realm/util/interprocess_condvar.hpp b/iOS/Pods/Realm/include/core/realm/util/interprocess_condvar.hpp new file mode 100644 index 0000000..0e5b586 --- /dev/null +++ b/iOS/Pods/Realm/include/core/realm/util/interprocess_condvar.hpp @@ -0,0 +1,151 @@ +/************************************************************************* + * + * Copyright 2016 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + **************************************************************************/ + +#ifndef REALM_UTIL_INTERPROCESS_CONDVAR +#define REALM_UTIL_INTERPROCESS_CONDVAR + + +#include +#include +#include +#include +#include +#include +#include + +// Condvar Emulation is required if RobustMutex emulation is enabled +#if defined(REALM_ROBUST_MUTEX_EMULATION) || defined(_WIN32) +#define REALM_CONDVAR_EMULATION +#endif + +namespace realm { +namespace util { + + +/// Condition variable for use in synchronization monitors. +/// This condition variable uses emulation based on named pipes +/// for the inter-process case, if enabled by REALM_CONDVAR_EMULATION. +/// +/// FIXME: This implementation will never release/delete pipes. This is unlikely +/// to be a problem as long as only a modest number of different database names +/// are in use +/// +/// A InterprocessCondVar is always process shared. +class InterprocessCondVar { +public: + InterprocessCondVar(); + ~InterprocessCondVar() noexcept; + + // Disable copying. Copying an open file will create a scenario + // where the same file descriptor will be opened once but closed twice. + InterprocessCondVar(const InterprocessCondVar&) = delete; + InterprocessCondVar& operator=(const InterprocessCondVar&) = delete; + +/// To use the InterprocessCondVar, you also must place a structure of type +/// InterprocessCondVar::SharedPart in memory shared by multiple processes +/// or in a memory mapped file, and use set_shared_part() to associate +/// the condition variable with it's shared part. You must initialize +/// the shared part using InterprocessCondVar::init_shared_part(), but only before +/// first use and only when you have exclusive access to the shared part. + +#ifdef REALM_CONDVAR_EMULATION + struct SharedPart { +#ifdef _WIN32 + // Number of waiting threads. + int32_t m_waiters_count; + size_t m_was_broadcast; +#else + uint64_t signal_counter; + uint64_t wait_counter; +#endif + }; +#else + typedef CondVar SharedPart; +#endif + + /// You need to bind the emulation to a SharedPart in shared/mmapped memory. + /// The SharedPart is assumed to have been initialized (possibly by another process) + /// earlier through a call to init_shared_part. + void set_shared_part(SharedPart& shared_part, std::string path, std::string condvar_name, std::string tmp_path); + + /// Initialize the shared part of a process shared condition variable. + /// A process shared condition variables may be represented by any number of + /// InterprocessCondVar instances in any number of different processes, + /// all sharing a common SharedPart instance, which must be in shared memory. + static void init_shared_part(SharedPart& shared_part); + + /// Release any system resources allocated for the shared part. This should + /// be used *only* when you are certain, that nobody is using it. + void release_shared_part(); + + /// Wait for someone to call notify() or notify_all() on this condition + /// variable. The call to wait() may return spuriously, so the caller should + /// always re-evaluate the condition on which to wait and loop on wait() + /// if necessary. + void wait(InterprocessMutex& m, const struct timespec* tp); + + /// If any threads are waiting for this condition, wake up at least one. + /// (Current implementation may actually wake all :-O ). The caller must + /// hold the lock associated with the condvar at the time of calling notify() + void notify() noexcept; + + /// Wake up every thread that is currently waiting on this condition. + /// The caller must hold the lock associated with the condvar at the time + /// of calling notify_all(). + void notify_all() noexcept; + + /// Cleanup and release system resources if possible. + void close() noexcept; + +private: + // non-zero if a shared part has been registered (always 0 on process local instances) + SharedPart* m_shared_part = nullptr; +#ifdef REALM_CONDVAR_EMULATION + // keep the path to allocated system resource so we can remove them again + std::string m_resource_path; + // pipe used for emulation. When using a named pipe, m_fd_read is read-write and m_fd_write is unused. + // When using an anonymous pipe (currently only for tvOS) m_fd_read is read-only and m_fd_write is write-only. + int m_fd_read = -1; + int m_fd_write = -1; + +#ifdef _WIN32 + // Semaphore used to queue up threads waiting for the condition to + // become signaled. + HANDLE m_sema = 0; + // An auto-reset event used by the broadcast/signal thread to wait + // for all the waiting thread(s) to wake up and be released from the + // semaphore. + HANDLE m_waiters_done = 0; + std::string m_name; + + // Serialize access to m_waiters_count + InterprocessMutex m_waiters_lockcount; +#endif + +#endif +}; + + +// Implementation: + + +} // namespace util +} // namespace realm + + +#endif