diff --git a/hoot-core/src/main/cpp/hoot/core/io/OsmApiWriter.h b/hoot-core/src/main/cpp/hoot/core/io/OsmApiWriter.h
index 67c1f6b..886588f 100644
--- a/hoot-core/src/main/cpp/hoot/core/io/OsmApiWriter.h
+++ b/hoot-core/src/main/cpp/hoot/core/io/OsmApiWriter.h
@@ -41,6 +41,7 @@
#include <tgs/System/Timer.h>
// Standard
+#include <condition_variable>
#include <mutex>
#include <queue>
#include <thread>
@@ -259,7 +260,7 @@ private:
* @param response String response from the server to help in the splitting process
* @return True if the changeset was split
*/
- bool _splitChangeset(const ChangesetInfoPtr& workInfo, const QString& response);
+ bool _splitChangeset(const ChangesetInfoPtr& workInfo, const QString& response = "");
/**
* @brief _writeDebugFile Write out the request or response file for debugging uploads
* @param type "request" or "response" output file
@@ -274,8 +275,24 @@ private:
* @return next ID
*/
int _getNextApiId();
+ /**
+ * @brief _allThreadsFailed Check if all threads are in the failed state
+ * @return true if all threads are in the failed state
+ */
+ bool _allThreadsFailed();
+ /**
+ * @brief _hasFailedThread Check if any thread is in a failed state
+ * @return true if any thread is in a failed state
+ */
+ bool _hasFailedThread();
/** Changeset processing thread pool */
std::vector<std::thread> _threadPool;
+ /**
+ * @brief _pushChangesets Push one or more changesets on to the work queue
+ * @param changeset Required changeset info object
+ * @param changeset2 Optional changeset info object
+ */
+ void _pushChangesets(ChangesetInfoPtr changeset, ChangesetInfoPtr changeset2 = ChangesetInfoPtr());
/** Queue for producer/consumer work model */
std::queue<ChangesetInfoPtr> _workQueue;
/** Mutex protecting work queue */
@@ -284,12 +301,41 @@ private:
XmlChangeset _changeset;
/** Mutex protecting large changeset */
std::mutex _changesetMutex;
+ /**
+ * @brief _startWork Tell the worker threads to begin processing work
+ */
+ void _startWork();
+ /**
+ * @brief _waitForStart Wait for the producer to signal to the consumers to begin work
+ */
+ void _waitForStart();
+ /** Mutex protecting start flag */
+ std::mutex _startMutex;
+ /** Condition variable to notify worker threads */
+ std::condition_variable _start;
+ /** Flag to tell worker threads to start processing */
+ bool _startFlag;
/** Status of each working thread, working or idle */
enum ThreadStatus
{
Idle,
- Working
+ Working,
+ Completed,
+ Failed,
+ Unknown
};
+ /**
+ * @brief _getThreadStatus Safely get the status of the thread
+ * @param thread_index Index of calling thread in _threadStatus vector
+ * @return Status of the thread
+ */
+ ThreadStatus _getThreadStatus(int thread_index);
+ /**
+ * @brief _updateThreadStatus Update the thread status
+ * @param thread_index Index of calling thread in _threadStatus vector
+ * @param status Status to update to
+ */
+ void _updateThreadStatus(int thread_index, ThreadStatus status);
/** Vector of statuses for each running thread */
std::vector<ThreadStatus> _threadStatus;
/** Mutex protecting status vector */
@@ -348,6 +394,8 @@ private:
int _apiId;
/** Mutex for API ID counter */
std::mutex _apiIdMutex;
+ /** Flag to tell threads that they can exit when idle */
+ bool _threadsCanExit;
/** For white box testing */
friend class OsmApiWriterTest;
/** Default constructor for testing purposes only */