This app provides monitoring and information features for the common freifunk user and the technical stuff of a freifunk community.
Code base is taken from a TUM Practical Course project and added here to see if Freifunk Altdorf can use it.
https://www.freifunk-altdorf.de
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
2.5 KiB
102 lines
2.5 KiB
/** |
|
* Copyright (c) 2015-present, Facebook, Inc. |
|
* |
|
* This source code is licensed under the MIT license found in the |
|
* LICENSE file in the root directory of this source tree. |
|
*/ |
|
|
|
#include "RCTMessageThread.h" |
|
|
|
#include <condition_variable> |
|
#include <mutex> |
|
|
|
#import <React/RCTCxxUtils.h> |
|
#import <React/RCTUtils.h> |
|
#include <jschelpers/JSCHelpers.h> |
|
|
|
// A note about the implementation: This class is not used |
|
// generically. It's a thin wrapper around a run loop which |
|
// implements a C++ interface, for use by the C++ xplat bridge code. |
|
// This means it can make certain non-generic assumptions. In |
|
// particular, the sync functions are only used for bridge setup and |
|
// teardown, and quitSynchronous is guaranteed to be called. |
|
|
|
namespace facebook { |
|
namespace react { |
|
|
|
RCTMessageThread::RCTMessageThread(NSRunLoop *runLoop, RCTJavaScriptCompleteBlock errorBlock) |
|
: m_cfRunLoop([runLoop getCFRunLoop]) |
|
, m_errorBlock(errorBlock) |
|
, m_shutdown(false) { |
|
CFRetain(m_cfRunLoop); |
|
} |
|
|
|
RCTMessageThread::~RCTMessageThread() { |
|
CFRelease(m_cfRunLoop); |
|
} |
|
|
|
// This is analogous to dispatch_async |
|
void RCTMessageThread::runAsync(std::function<void()> func) { |
|
CFRunLoopPerformBlock(m_cfRunLoop, kCFRunLoopCommonModes, ^{ func(); }); |
|
CFRunLoopWakeUp(m_cfRunLoop); |
|
} |
|
|
|
// This is analogous to dispatch_sync |
|
void RCTMessageThread::runSync(std::function<void()> func) { |
|
if (m_cfRunLoop == CFRunLoopGetCurrent()) { |
|
func(); |
|
return; |
|
} |
|
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0); |
|
runAsync([func=std::make_shared<std::function<void()>>(std::move(func)), &sema] { |
|
(*func)(); |
|
dispatch_semaphore_signal(sema); |
|
}); |
|
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); |
|
} |
|
|
|
void RCTMessageThread::tryFunc(const std::function<void()>& func) { |
|
NSError *error = tryAndReturnError(func); |
|
if (error) { |
|
m_errorBlock(error); |
|
} |
|
} |
|
|
|
void RCTMessageThread::runOnQueue(std::function<void()>&& func) { |
|
if (m_shutdown) { |
|
return; |
|
} |
|
|
|
runAsync([this, func=std::make_shared<std::function<void()>>(std::move(func))] { |
|
if (!m_shutdown) { |
|
tryFunc(*func); |
|
} |
|
}); |
|
} |
|
|
|
void RCTMessageThread::runOnQueueSync(std::function<void()>&& func) { |
|
if (m_shutdown) { |
|
return; |
|
} |
|
runSync([this, func=std::move(func)] { |
|
if (!m_shutdown) { |
|
tryFunc(func); |
|
} |
|
}); |
|
} |
|
|
|
void RCTMessageThread::quitSynchronous() { |
|
m_shutdown = true; |
|
runSync([]{}); |
|
CFRunLoopStop(m_cfRunLoop); |
|
} |
|
|
|
void RCTMessageThread::setRunLoop(NSRunLoop *runLoop) { |
|
CFRelease(m_cfRunLoop); |
|
m_cfRunLoop = [runLoop getCFRunLoop]; |
|
CFRetain(m_cfRunLoop); |
|
} |
|
|
|
} |
|
}
|
|
|