Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
AsyncOp.cpp
00001 /* 00002 * Copyright (c) 2018-2019, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #include "AsyncOp.h" 00019 #include "mbed_critical.h" 00020 #include "mbed_assert.h" 00021 00022 using namespace rtos; 00023 00024 AsyncOp::AsyncOp(): 00025 _list(NULL), _wait(NULL), _aborted(false), _timeout(false) 00026 { 00027 00028 } 00029 00030 AsyncOp::AsyncOp(mbed::Callback<void()> &callback): 00031 _list(NULL), _wait(NULL), _aborted(false), _timeout(false) 00032 { 00033 _callback = callback; 00034 } 00035 00036 AsyncOp::~AsyncOp() 00037 { 00038 MBED_ASSERT(_list == NULL); 00039 } 00040 00041 void AsyncOp::wait(rtos::Mutex *host_mutex, uint32_t milliseconds) 00042 { 00043 // Optimization so semaphore is only created if necessary 00044 core_util_critical_section_enter(); 00045 bool done = _list == NULL; 00046 core_util_critical_section_exit(); 00047 if (done) { 00048 return; 00049 } 00050 00051 // Construct semaphore to wait on 00052 Semaphore sem(0); 00053 00054 core_util_critical_section_enter(); 00055 done = _list == NULL; 00056 // Wait is only allowed to be called from one thread 00057 MBED_ASSERT(_wait == NULL); 00058 _wait = &sem; 00059 core_util_critical_section_exit(); 00060 00061 if (done) { 00062 // Operation was signaled before semaphore was set 00063 return; 00064 } 00065 00066 if (sem.try_acquire_for(milliseconds)) { 00067 // Operation completion signaled semaphore 00068 return; 00069 } 00070 00071 _host_lock(host_mutex); 00072 _abort(true); 00073 _host_unlock(host_mutex); 00074 } 00075 00076 void AsyncOp::abort() 00077 { 00078 // Host lock must be held 00079 00080 _abort(false); 00081 } 00082 00083 void AsyncOp::complete() 00084 { 00085 core_util_critical_section_enter(); 00086 00087 mbed::Callback<void()> cb = _callback; 00088 _callback = NULL; 00089 _list = NULL; 00090 if (_wait != NULL) { 00091 _wait->release(); 00092 } 00093 00094 core_util_critical_section_exit(); 00095 00096 if (cb) { 00097 cb(); 00098 } 00099 } 00100 00101 bool AsyncOp::timeout() 00102 { 00103 core_util_critical_section_enter(); 00104 00105 bool ret = _timeout; 00106 00107 core_util_critical_section_exit(); 00108 return ret; 00109 } 00110 00111 void AsyncOp::_abort(bool timeout) 00112 { 00113 // host lock must be held 00114 00115 core_util_critical_section_enter(); 00116 OperationListBase *list = _list; 00117 if (list) { 00118 _callback = NULL; 00119 _aborted = true; 00120 _wait = NULL; 00121 _timeout = timeout; 00122 _list = NULL; 00123 } 00124 core_util_critical_section_exit(); 00125 if (list) { 00126 list->remove(this); 00127 } 00128 } 00129 00130 void AsyncOp::_host_lock(rtos::Mutex *host_mutex) 00131 { 00132 if (host_mutex) { 00133 host_mutex->lock(); 00134 } else { 00135 core_util_critical_section_enter(); 00136 } 00137 } 00138 00139 void AsyncOp::_host_unlock(rtos::Mutex *host_mutex) 00140 { 00141 if (host_mutex) { 00142 host_mutex->unlock(); 00143 } else { 00144 core_util_critical_section_exit(); 00145 } 00146 }
Generated on Tue Jul 12 2022 13:54:01 by
