Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * include/stxxl/bits/io/request_operations.h 00003 * 00004 * Part of the STXXL. See http://stxxl.sourceforge.net 00005 * 00006 * Copyright (C) 2002 Roman Dementiev <dementiev@mpi-sb.mpg.de> 00007 * Copyright (C) 2008, 2009 Andreas Beckmann <beckmann@cs.uni-frankfurt.de> 00008 * Copyright (C) 2009 Johannes Singler <singler@ira.uka.de> 00009 * 00010 * Distributed under the Boost Software License, Version 1.0. 00011 * (See accompanying file LICENSE_1_0.txt or copy at 00012 * http://www.boost.org/LICENSE_1_0.txt) 00013 **************************************************************************/ 00014 00015 #ifndef STXXL_IO__REQUEST_OPERATIONS_H_ 00016 #define STXXL_IO__REQUEST_OPERATIONS_H_ 00017 00018 #include <stxxl/bits/namespace.h> 00019 #include <stxxl/bits/io/request_ptr.h> 00020 #include <stxxl/bits/io/iostats.h> 00021 #include <stxxl/bits/common/switch.h> 00022 00023 00024 __STXXL_BEGIN_NAMESPACE 00025 00026 //! \addtogroup iolayer 00027 //! \{ 00028 00029 //! \brief Collection of functions to track statuses of a number of requests 00030 00031 00032 //! \brief Suspends calling thread until \b all given requests are completed 00033 //! \param reqs_begin begin of request sequence to wait for 00034 //! \param reqs_end end of request sequence to wait for 00035 template <class request_iterator_> 00036 void wait_all(request_iterator_ reqs_begin, request_iterator_ reqs_end) 00037 { 00038 for ( ; reqs_begin != reqs_end; ++reqs_begin) 00039 (request_ptr(*reqs_begin))->wait(); 00040 } 00041 00042 //! \brief Suspends calling thread until \b all given requests are completed 00043 //! \param req_array array of request_ptr objects 00044 //! \param count size of req_array 00045 inline void wait_all(request_ptr req_array[], int count) 00046 { 00047 wait_all(req_array, req_array + count); 00048 } 00049 00050 //! \brief Cancel requests 00051 //! The specified requests are canceled unless already being processed. 00052 //! However, cancelation cannot be guaranteed. 00053 //! Cancelled requests must still be waited for in order to ensure correct 00054 //! operation. 00055 //! \param reqs_begin begin of request sequence 00056 //! \param reqs_end end of request sequence 00057 //! \return number of request canceled 00058 template <class request_iterator_> 00059 typename std::iterator_traits<request_iterator_>::difference_type cancel_all(request_iterator_ reqs_begin, request_iterator_ reqs_end) 00060 { 00061 typename std::iterator_traits<request_iterator_>::difference_type num_canceled = 0; 00062 while (reqs_begin != reqs_end) 00063 { 00064 if ((request_ptr(*reqs_begin))->cancel()) 00065 ++num_canceled; 00066 ++reqs_begin; 00067 } 00068 return num_canceled; 00069 } 00070 00071 //! \brief Polls requests 00072 //! \param reqs_begin begin of request sequence to poll 00073 //! \param reqs_end end of request sequence to poll 00074 //! \param index contains index of the \b first completed request if any 00075 //! \return \c true if any of requests is completed, then index contains valid value, otherwise \c false 00076 template <class request_iterator_> 00077 request_iterator_ poll_any(request_iterator_ reqs_begin, request_iterator_ reqs_end) 00078 { 00079 while (reqs_begin != reqs_end) 00080 { 00081 if ((request_ptr(*reqs_begin))->poll()) 00082 return reqs_begin; 00083 00084 ++reqs_begin; 00085 } 00086 return reqs_end; 00087 } 00088 00089 00090 //! \brief Polls requests 00091 //! \param req_array array of request_ptr objects 00092 //! \param count size of req_array 00093 //! \param index contains index of the \b first completed request if any 00094 //! \return \c true if any of requests is completed, then index contains valid value, otherwise \c false 00095 inline bool poll_any(request_ptr req_array[], int count, int & index) 00096 { 00097 request_ptr * res = poll_any(req_array, req_array + count); 00098 index = res - req_array; 00099 return res != (req_array + count); 00100 } 00101 00102 00103 //! \brief Suspends calling thread until \b any of requests is completed 00104 //! \param reqs_begin begin of request sequence to wait for 00105 //! \param reqs_end end of request sequence to wait for 00106 //! \return index in req_array pointing to the \b first completed request 00107 template <class request_iterator_> 00108 request_iterator_ wait_any(request_iterator_ reqs_begin, request_iterator_ reqs_end) 00109 { 00110 stats::scoped_wait_timer wait_timer(stats::WAIT_OP_ANY); 00111 00112 onoff_switch sw; 00113 00114 request_iterator_ cur = reqs_begin, result = reqs_end; 00115 00116 for ( ; cur != reqs_end; cur++) 00117 { 00118 if ((request_ptr(*cur))->add_waiter(&sw)) 00119 { 00120 // request is already done, no waiter was added to the request 00121 result = cur; 00122 00123 if (cur != reqs_begin) 00124 { 00125 while (--cur != reqs_begin) 00126 (request_ptr(*cur))->delete_waiter(&sw); 00127 00128 (request_ptr(*cur))->delete_waiter(&sw); 00129 } 00130 00131 (request_ptr(*result))->check_errors(); 00132 00133 return result; 00134 } 00135 } 00136 00137 sw.wait_for_on(); 00138 00139 for (cur = reqs_begin; cur != reqs_end; cur++) 00140 { 00141 (request_ptr(*cur))->delete_waiter(&sw); 00142 if (result == reqs_end && (request_ptr(*cur))->poll()) 00143 result = cur; 00144 } 00145 00146 return result; 00147 } 00148 00149 00150 //! \brief Suspends calling thread until \b any of requests is completed 00151 //! \param req_array array of \c request_ptr objects 00152 //! \param count size of req_array 00153 //! \return index in req_array pointing to the \b first completed request 00154 inline int wait_any(request_ptr req_array[], int count) 00155 { 00156 return wait_any(req_array, req_array + count) - req_array; 00157 } 00158 00159 //! \} 00160 00161 __STXXL_END_NAMESPACE 00162 00163 #endif // !STXXL_IO__REQUEST_OPERATIONS_H_ 00164 // vim: et:ts=4:sw=4