Stxxl  1.4.0
include/stxxl/bits/io/request_operations.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines