libkea_util_la_SOURCES = boost_time_utils.h boost_time_utils.cc
libkea_util_la_SOURCES += csv_file.h csv_file.cc
libkea_util_la_SOURCES += filename.h filename.cc
-libkea_util_la_SOURCES += fork_detector.h
libkea_util_la_SOURCES += strutil.h strutil.cc
libkea_util_la_SOURCES += buffer.h io_utilities.h
libkea_util_la_SOURCES += time_utilities.h time_utilities.cc
+++ /dev/null
-// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#ifndef FORK_DETECTOR_H
-#define FORK_DETECTOR_H
-
-#include <sys/types.h>
-#include <unistd.h>
-
-namespace isc {
-namespace util {
-
-/// @brief Class which detects being child process.
-///
-/// This class detects if it is in the child process, by checking if the
-/// process PID matches the PID of the process which created instance of
-/// the class.
-///
-/// Detecting if we're in the child process is important when the application
-/// spawns new process using fork/exec. If exec step fails for any reason
-/// the child process exits. However, to exit gracefully the process may
-/// need to know if it is a child or parent and take a different path
-/// during destruction.
-class ForkDetector {
-public:
-
- /// @brief Constructor.
- ///
- /// Stores the PID of the process creating this instance.
- ForkDetector()
- : creator_pid_(getpid()) {
- }
-
- /// @brief Check if the process is a parent process;
- ///
- /// @return true if the process is a parent process.
- bool isParent() const {
- return (getpid() == creator_pid_);
- }
-
-private:
-
- /// @brief PID of the process which created instance of this class.
- pid_t creator_pid_;
-
-};
-
-} // namespace isc::util
-} // namespace isc
-
-#endif // FORK_DETECTOR_H
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#include <util/fork_detector.h>
#include <util/threads/thread.h>
#include <util/threads/sync.h>
// and the creating thread needs to release it.
waiting_(2),
main_(main),
- exception_(false),
- fork_detector_()
+ exception_(false)
{}
// Another of the waiting events is done. If there are no more, delete
// impl.
Mutex mutex_;
// Which thread are we talking about anyway?
pthread_t tid_;
- // Class to detect if we're in the child or parent process.
- ForkDetector fork_detector_;
};
Thread::Thread(const boost::function<void ()>& main) :
Thread::~Thread() {
if (impl_ != NULL) {
-
- int result = pthread_detach(impl_->tid_);
- // If the error indicates that thread doesn't exist but we're
- // in child process (after fork) it is expected. We should
- // not cause an assert.
- if (result == ESRCH && !impl_->fork_detector_.isParent()) {
- result = 0;
- }
-
+ // In case we didn't call wait yet
+ const int result = pthread_detach(impl_->tid_);
Impl::done(impl_);
impl_ = NULL;
// If the detach ever fails, something is screwed rather badly.
"Wait called and no thread to wait for");
}
- // Was there an exception in the thread?
- scoped_ptr<UncaughtException> ex;
-
const int result = pthread_join(impl_->tid_, NULL);
if (result != 0) {
- // We will not throw exception if the error indicates that the
- // thread doesn't exist and we are in the child process (forked).
- // For the child process it is expected that the thread is not
- // re-created when we fork.
- if (result != ESRCH || impl_->fork_detector_.isParent()) {
- isc_throw(isc::InvalidOperation, std::strerror(result));
- }
+ isc_throw(isc::InvalidOperation, std::strerror(result));
}
+ // Was there an exception in the thread?
+ scoped_ptr<UncaughtException> ex;
// Something here could in theory throw. But we already terminated the thread, so
// we need to make sure we are in consistent state even in such situation (like
// releasing the mutex and impl_).