peerplays-fc/include/boost/process/handle.hpp
2012-12-19 12:23:12 -05:00

231 lines
5.6 KiB
C++

//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
// Copyright (c) 2009 Boris Schaeling
// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
/**
* \file boost/process/handle.hpp
*
* Includes the declaration of the handle class.
*/
#ifndef BOOST_PROCESS_HANDLE_HPP
#define BOOST_PROCESS_HANDLE_HPP
#include <boost/process/config.hpp>
#if defined(BOOST_POSIX_API)
# include <unistd.h>
#elif defined(BOOST_WINDOWS_API)
# include <windows.h>
#else
# error "Unsupported platform."
#endif
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
namespace boost {
namespace process {
/**
* RAII model for handles.
*
* The \a handle class is a RAII model for native handles. This class wraps
* one of such handles grabbing its ownership, and automaticaly closes it
* upon destruction. It is used to avoid leaking open handles, shall an
* unexpected execution trace occur.
*/
class handle
{
public:
#if defined(BOOST_PROCESS_DOXYGEN)
/**
* Opaque name for the native handle type.
*
* On POSIX systems \a NativeSystemHandle is an integer type while it is
* a \a HANDLE on Windows systems.
*/
typedef NativeSystemHandle native_type;
#elif defined(BOOST_POSIX_API)
typedef int native_type;
#elif defined(BOOST_WINDOWS_API)
typedef HANDLE native_type;
#endif
/**
* Constructs an invalid handle.
*
* \see valid()
*/
handle()
{
}
/**
* RAII settings to specify if handle should be automatically closed.
*/
enum close_type { do_close, dont_close };
/**
* Constructs a handle from a native handle.
*
* This constructor creates a new \a handle object that takes
* ownership of the given \a native handle. If \a close is set to
* handle::dont_close the \a native handle is not closed upon destruction.
* The user must not close \a native if it is owned by a \a handle object.
* Ownership can be reclaimed using release().
*
* \see release()
*/
handle(native_type native, close_type close = handle::do_close)
: impl_(boost::make_shared<impl>(native, close))
{
}
/**
* Checks whether the handle is valid or not.
*
* \return true if the handle is valid; false otherwise.
*/
bool valid() const
{
return impl_ && impl_->valid();
}
/**
* Closes the handle.
*
* \post The handle is invalid.
* \post The native handle is closed.
*/
void close()
{
if (impl_)
impl_->close();
}
/**
* Gets the native handle.
*
* The caller can issue any operation on it except closing it.
* If closing is required, release() shall be used.
*
* \return The native handle.
*/
native_type native() const
{
return impl_ ? impl_->native() : invalid_handle();
}
/**
* Reclaims ownership of the native handle.
*
* The caller is responsible of closing the native handle.
*
* \post The handle is invalid.
* \return The native handle.
*/
native_type release()
{
return impl_ ? impl_->release() : invalid_handle();
}
private:
class impl
{
public:
typedef handle::native_type native_type;
impl(native_type native, close_type close)
: native_(native),
close_(close)
{
}
~impl()
{
if (valid() && close_ == handle::do_close)
{
#if defined(BOOST_POSIX_API)
::close(native_);
#elif defined(BOOST_WINDOWS_API)
CloseHandle(native_);
#endif
}
}
bool valid() const
{
return native_ != handle::invalid_handle();
}
void close()
{
if (valid())
{
#if defined(BOOST_POSIX_API)
::close(native_);
#elif defined(BOOST_WINDOWS_API)
CloseHandle(native_);
#endif
native_ = handle::invalid_handle();
}
}
native_type native() const
{
return native_;
}
native_type release()
{
native_type native = native_;
native_ = handle::invalid_handle();
return native;
}
private:
native_type native_;
close_type close_;
};
/**
* Implementation of handle to store native handle value.
*
* A shared pointer is used as handles represent system resources. If a
* handle is closed and becomes invalid the state of copies of the handle
* object will be updated as they all share the handle implementation.
*/
boost::shared_ptr<impl> impl_;
/**
* Constant function representing an invalid handle value.
*
* Returns the platform-specific handle value that represents an
* invalid handle. This is a constant function rather than a regular
* constant because, in the latter case, we cannot define it under
* Windows due to the value being of a complex type.
*/
static const native_type invalid_handle()
{
#if defined(BOOST_POSIX_API)
return -1;
#elif defined(BOOST_WINDOWS_API)
return INVALID_HANDLE_VALUE;
#endif
}
};
}
}
#endif