81a91c442606b6cd6f4d4c28eb31e441c1531cf7
[platform/upstream/boost.git] / boost / asio / posix / basic_descriptor.hpp
1 //
2 // posix/basic_descriptor.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10
11 #ifndef BOOST_ASIO_POSIX_BASIC_DESCRIPTOR_HPP
12 #define BOOST_ASIO_POSIX_BASIC_DESCRIPTOR_HPP
13
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18 #include <boost/asio/detail/config.hpp>
19
20 #if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \
21   || defined(GENERATING_DOCUMENTATION)
22
23 #include <boost/asio/basic_io_object.hpp>
24 #include <boost/asio/detail/throw_error.hpp>
25 #include <boost/asio/error.hpp>
26 #include <boost/asio/posix/descriptor_base.hpp>
27
28 #include <boost/asio/detail/push_options.hpp>
29
30 namespace boost {
31 namespace asio {
32 namespace posix {
33
34 /// Provides POSIX descriptor functionality.
35 /**
36  * The posix::basic_descriptor class template provides the ability to wrap a
37  * POSIX descriptor.
38  *
39  * @par Thread Safety
40  * @e Distinct @e objects: Safe.@n
41  * @e Shared @e objects: Unsafe.
42  */
43 template <typename DescriptorService>
44 class basic_descriptor
45   : public basic_io_object<DescriptorService>,
46     public descriptor_base
47 {
48 public:
49   /// (Deprecated: Use native_handle_type.) The native representation of a
50   /// descriptor.
51   typedef typename DescriptorService::native_handle_type native_type;
52
53   /// The native representation of a descriptor.
54   typedef typename DescriptorService::native_handle_type native_handle_type;
55
56   /// A basic_descriptor is always the lowest layer.
57   typedef basic_descriptor<DescriptorService> lowest_layer_type;
58
59   /// Construct a basic_descriptor without opening it.
60   /**
61    * This constructor creates a descriptor without opening it.
62    *
63    * @param io_service The io_service object that the descriptor will use to
64    * dispatch handlers for any asynchronous operations performed on the
65    * descriptor.
66    */
67   explicit basic_descriptor(boost::asio::io_service& io_service)
68     : basic_io_object<DescriptorService>(io_service)
69   {
70   }
71
72   /// Construct a basic_descriptor on an existing native descriptor.
73   /**
74    * This constructor creates a descriptor object to hold an existing native
75    * descriptor.
76    *
77    * @param io_service The io_service object that the descriptor will use to
78    * dispatch handlers for any asynchronous operations performed on the
79    * descriptor.
80    *
81    * @param native_descriptor A native descriptor.
82    *
83    * @throws boost::system::system_error Thrown on failure.
84    */
85   basic_descriptor(boost::asio::io_service& io_service,
86       const native_handle_type& native_descriptor)
87     : basic_io_object<DescriptorService>(io_service)
88   {
89     boost::system::error_code ec;
90     this->get_service().assign(this->get_implementation(),
91         native_descriptor, ec);
92     boost::asio::detail::throw_error(ec, "assign");
93   }
94
95 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
96   /// Move-construct a basic_descriptor from another.
97   /**
98    * This constructor moves a descriptor from one object to another.
99    *
100    * @param other The other basic_descriptor object from which the move will
101    * occur.
102    *
103    * @note Following the move, the moved-from object is in the same state as if
104    * constructed using the @c basic_descriptor(io_service&) constructor.
105    */
106   basic_descriptor(basic_descriptor&& other)
107     : basic_io_object<DescriptorService>(
108         BOOST_ASIO_MOVE_CAST(basic_descriptor)(other))
109   {
110   }
111
112   /// Move-assign a basic_descriptor from another.
113   /**
114    * This assignment operator moves a descriptor from one object to another.
115    *
116    * @param other The other basic_descriptor object from which the move will
117    * occur.
118    *
119    * @note Following the move, the moved-from object is in the same state as if
120    * constructed using the @c basic_descriptor(io_service&) constructor.
121    */
122   basic_descriptor& operator=(basic_descriptor&& other)
123   {
124     basic_io_object<DescriptorService>::operator=(
125         BOOST_ASIO_MOVE_CAST(basic_descriptor)(other));
126     return *this;
127   }
128 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
129
130   /// Get a reference to the lowest layer.
131   /**
132    * This function returns a reference to the lowest layer in a stack of
133    * layers. Since a basic_descriptor cannot contain any further layers, it
134    * simply returns a reference to itself.
135    *
136    * @return A reference to the lowest layer in the stack of layers. Ownership
137    * is not transferred to the caller.
138    */
139   lowest_layer_type& lowest_layer()
140   {
141     return *this;
142   }
143
144   /// Get a const reference to the lowest layer.
145   /**
146    * This function returns a const reference to the lowest layer in a stack of
147    * layers. Since a basic_descriptor cannot contain any further layers, it
148    * simply returns a reference to itself.
149    *
150    * @return A const reference to the lowest layer in the stack of layers.
151    * Ownership is not transferred to the caller.
152    */
153   const lowest_layer_type& lowest_layer() const
154   {
155     return *this;
156   }
157
158   /// Assign an existing native descriptor to the descriptor.
159   /*
160    * This function opens the descriptor to hold an existing native descriptor.
161    *
162    * @param native_descriptor A native descriptor.
163    *
164    * @throws boost::system::system_error Thrown on failure.
165    */
166   void assign(const native_handle_type& native_descriptor)
167   {
168     boost::system::error_code ec;
169     this->get_service().assign(this->get_implementation(),
170         native_descriptor, ec);
171     boost::asio::detail::throw_error(ec, "assign");
172   }
173
174   /// Assign an existing native descriptor to the descriptor.
175   /*
176    * This function opens the descriptor to hold an existing native descriptor.
177    *
178    * @param native_descriptor A native descriptor.
179    *
180    * @param ec Set to indicate what error occurred, if any.
181    */
182   boost::system::error_code assign(const native_handle_type& native_descriptor,
183       boost::system::error_code& ec)
184   {
185     return this->get_service().assign(
186         this->get_implementation(), native_descriptor, ec);
187   }
188
189   /// Determine whether the descriptor is open.
190   bool is_open() const
191   {
192     return this->get_service().is_open(this->implementation);
193   }
194
195   /// Close the descriptor.
196   /**
197    * This function is used to close the descriptor. Any asynchronous read or
198    * write operations will be cancelled immediately, and will complete with the
199    * boost::asio::error::operation_aborted error.
200    *
201    * @throws boost::system::system_error Thrown on failure. Note that, even if
202    * the function indicates an error, the underlying descriptor is closed.
203    */
204   void close()
205   {
206     boost::system::error_code ec;
207     this->get_service().close(this->get_implementation(), ec);
208     boost::asio::detail::throw_error(ec, "close");
209   }
210
211   /// Close the descriptor.
212   /**
213    * This function is used to close the descriptor. Any asynchronous read or
214    * write operations will be cancelled immediately, and will complete with the
215    * boost::asio::error::operation_aborted error.
216    *
217    * @param ec Set to indicate what error occurred, if any. Note that, even if
218    * the function indicates an error, the underlying descriptor is closed.
219    */
220   boost::system::error_code close(boost::system::error_code& ec)
221   {
222     return this->get_service().close(this->get_implementation(), ec);
223   }
224
225   /// (Deprecated: Use native_handle().) Get the native descriptor
226   /// representation.
227   /**
228    * This function may be used to obtain the underlying representation of the
229    * descriptor. This is intended to allow access to native descriptor
230    * functionality that is not otherwise provided.
231    */
232   native_type native()
233   {
234     return this->get_service().native_handle(this->implementation);
235   }
236
237   /// Get the native descriptor representation.
238   /**
239    * This function may be used to obtain the underlying representation of the
240    * descriptor. This is intended to allow access to native descriptor
241    * functionality that is not otherwise provided.
242    */
243   native_handle_type native_handle()
244   {
245     return this->get_service().native_handle(this->implementation);
246   }
247
248   /// Release ownership of the native descriptor implementation.
249   /**
250    * This function may be used to obtain the underlying representation of the
251    * descriptor. After calling this function, @c is_open() returns false. The
252    * caller is responsible for closing the descriptor.
253    *
254    * All outstanding asynchronous read or write operations will finish
255    * immediately, and the handlers for cancelled operations will be passed the
256    * boost::asio::error::operation_aborted error.
257    */
258   native_handle_type release()
259   {
260     return this->get_service().release(this->implementation);
261   }
262
263   /// Cancel all asynchronous operations associated with the descriptor.
264   /**
265    * This function causes all outstanding asynchronous read or write operations
266    * to finish immediately, and the handlers for cancelled operations will be
267    * passed the boost::asio::error::operation_aborted error.
268    *
269    * @throws boost::system::system_error Thrown on failure.
270    */
271   void cancel()
272   {
273     boost::system::error_code ec;
274     this->get_service().cancel(this->get_implementation(), ec);
275     boost::asio::detail::throw_error(ec, "cancel");
276   }
277
278   /// Cancel all asynchronous operations associated with the descriptor.
279   /**
280    * This function causes all outstanding asynchronous read or write operations
281    * to finish immediately, and the handlers for cancelled operations will be
282    * passed the boost::asio::error::operation_aborted error.
283    *
284    * @param ec Set to indicate what error occurred, if any.
285    */
286   boost::system::error_code cancel(boost::system::error_code& ec)
287   {
288     return this->get_service().cancel(this->get_implementation(), ec);
289   }
290
291   /// Perform an IO control command on the descriptor.
292   /**
293    * This function is used to execute an IO control command on the descriptor.
294    *
295    * @param command The IO control command to be performed on the descriptor.
296    *
297    * @throws boost::system::system_error Thrown on failure.
298    *
299    * @sa IoControlCommand @n
300    * boost::asio::posix::descriptor_base::bytes_readable @n
301    * boost::asio::posix::descriptor_base::non_blocking_io
302    *
303    * @par Example
304    * Getting the number of bytes ready to read:
305    * @code
306    * boost::asio::posix::stream_descriptor descriptor(io_service);
307    * ...
308    * boost::asio::posix::stream_descriptor::bytes_readable command;
309    * descriptor.io_control(command);
310    * std::size_t bytes_readable = command.get();
311    * @endcode
312    */
313   template <typename IoControlCommand>
314   void io_control(IoControlCommand& command)
315   {
316     boost::system::error_code ec;
317     this->get_service().io_control(this->get_implementation(), command, ec);
318     boost::asio::detail::throw_error(ec, "io_control");
319   }
320
321   /// Perform an IO control command on the descriptor.
322   /**
323    * This function is used to execute an IO control command on the descriptor.
324    *
325    * @param command The IO control command to be performed on the descriptor.
326    *
327    * @param ec Set to indicate what error occurred, if any.
328    *
329    * @sa IoControlCommand @n
330    * boost::asio::posix::descriptor_base::bytes_readable @n
331    * boost::asio::posix::descriptor_base::non_blocking_io
332    *
333    * @par Example
334    * Getting the number of bytes ready to read:
335    * @code
336    * boost::asio::posix::stream_descriptor descriptor(io_service);
337    * ...
338    * boost::asio::posix::stream_descriptor::bytes_readable command;
339    * boost::system::error_code ec;
340    * descriptor.io_control(command, ec);
341    * if (ec)
342    * {
343    *   // An error occurred.
344    * }
345    * std::size_t bytes_readable = command.get();
346    * @endcode
347    */
348   template <typename IoControlCommand>
349   boost::system::error_code io_control(IoControlCommand& command,
350       boost::system::error_code& ec)
351   {
352     return this->get_service().io_control(
353         this->get_implementation(), command, ec);
354   }
355
356   /// Gets the non-blocking mode of the descriptor.
357   /**
358    * @returns @c true if the descriptor's synchronous operations will fail with
359    * boost::asio::error::would_block if they are unable to perform the requested
360    * operation immediately. If @c false, synchronous operations will block
361    * until complete.
362    *
363    * @note The non-blocking mode has no effect on the behaviour of asynchronous
364    * operations. Asynchronous operations will never fail with the error
365    * boost::asio::error::would_block.
366    */
367   bool non_blocking() const
368   {
369     return this->get_service().non_blocking(this->implementation);
370   }
371
372   /// Sets the non-blocking mode of the descriptor.
373   /**
374    * @param mode If @c true, the descriptor's synchronous operations will fail
375    * with boost::asio::error::would_block if they are unable to perform the
376    * requested operation immediately. If @c false, synchronous operations will
377    * block until complete.
378    *
379    * @throws boost::system::system_error Thrown on failure.
380    *
381    * @note The non-blocking mode has no effect on the behaviour of asynchronous
382    * operations. Asynchronous operations will never fail with the error
383    * boost::asio::error::would_block.
384    */
385   void non_blocking(bool mode)
386   {
387     boost::system::error_code ec;
388     this->get_service().non_blocking(this->get_implementation(), mode, ec);
389     boost::asio::detail::throw_error(ec, "non_blocking");
390   }
391
392   /// Sets the non-blocking mode of the descriptor.
393   /**
394    * @param mode If @c true, the descriptor's synchronous operations will fail
395    * with boost::asio::error::would_block if they are unable to perform the
396    * requested operation immediately. If @c false, synchronous operations will
397    * block until complete.
398    *
399    * @param ec Set to indicate what error occurred, if any.
400    *
401    * @note The non-blocking mode has no effect on the behaviour of asynchronous
402    * operations. Asynchronous operations will never fail with the error
403    * boost::asio::error::would_block.
404    */
405   boost::system::error_code non_blocking(
406       bool mode, boost::system::error_code& ec)
407   {
408     return this->get_service().non_blocking(
409         this->get_implementation(), mode, ec);
410   }
411
412   /// Gets the non-blocking mode of the native descriptor implementation.
413   /**
414    * This function is used to retrieve the non-blocking mode of the underlying
415    * native descriptor. This mode has no effect on the behaviour of the
416    * descriptor object's synchronous operations.
417    *
418    * @returns @c true if the underlying descriptor is in non-blocking mode and
419    * direct system calls may fail with boost::asio::error::would_block (or the
420    * equivalent system error).
421    *
422    * @note The current non-blocking mode is cached by the descriptor object.
423    * Consequently, the return value may be incorrect if the non-blocking mode
424    * was set directly on the native descriptor.
425    */
426   bool native_non_blocking() const
427   {
428     return this->get_service().native_non_blocking(this->implementation);
429   }
430
431   /// Sets the non-blocking mode of the native descriptor implementation.
432   /**
433    * This function is used to modify the non-blocking mode of the underlying
434    * native descriptor. It has no effect on the behaviour of the descriptor
435    * object's synchronous operations.
436    *
437    * @param mode If @c true, the underlying descriptor is put into non-blocking
438    * mode and direct system calls may fail with boost::asio::error::would_block
439    * (or the equivalent system error).
440    *
441    * @throws boost::system::system_error Thrown on failure. If the @c mode is
442    * @c false, but the current value of @c non_blocking() is @c true, this
443    * function fails with boost::asio::error::invalid_argument, as the
444    * combination does not make sense.
445    */
446   void native_non_blocking(bool mode)
447   {
448     boost::system::error_code ec;
449     this->get_service().native_non_blocking(
450         this->get_implementation(), mode, ec);
451     boost::asio::detail::throw_error(ec, "native_non_blocking");
452   }
453
454   /// Sets the non-blocking mode of the native descriptor implementation.
455   /**
456    * This function is used to modify the non-blocking mode of the underlying
457    * native descriptor. It has no effect on the behaviour of the descriptor
458    * object's synchronous operations.
459    *
460    * @param mode If @c true, the underlying descriptor is put into non-blocking
461    * mode and direct system calls may fail with boost::asio::error::would_block
462    * (or the equivalent system error).
463    *
464    * @param ec Set to indicate what error occurred, if any. If the @c mode is
465    * @c false, but the current value of @c non_blocking() is @c true, this
466    * function fails with boost::asio::error::invalid_argument, as the
467    * combination does not make sense.
468    */
469   boost::system::error_code native_non_blocking(
470       bool mode, boost::system::error_code& ec)
471   {
472     return this->get_service().native_non_blocking(
473         this->get_implementation(), mode, ec);
474   }
475
476 protected:
477   /// Protected destructor to prevent deletion through this type.
478   ~basic_descriptor()
479   {
480   }
481 };
482
483 } // namespace posix
484 } // namespace asio
485 } // namespace boost
486
487 #include <boost/asio/detail/pop_options.hpp>
488
489 #endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
490        //   || defined(GENERATING_DOCUMENTATION)
491
492 #endif // BOOST_ASIO_POSIX_BASIC_DESCRIPTOR_HPP