+ u16 &count_peer = it2->second;
+ assert(count_peer != 0);
+ count_peer--;
+
+ m_blocks_enqueued.erase(it);
+
+ return true;
+}
+
+
+EmergeThread *EmergeManager::getOptimalThread()
+{
+ size_t nthreads = m_threads.size();
+
+ FATAL_ERROR_IF(nthreads == 0, "No emerge threads!");
+
+ size_t index = 0;
+ size_t nitems_lowest = m_threads[0]->m_block_queue.size();
+
+ for (size_t i = 1; i < nthreads; i++) {
+ size_t nitems = m_threads[i]->m_block_queue.size();
+ if (nitems < nitems_lowest) {
+ index = i;
+ nitems_lowest = nitems;
+ }
+ }
+
+ return m_threads[index];
+}
+
+
+////
+//// EmergeThread
+////
+
+EmergeThread::EmergeThread(Server *server, int ethreadid) :
+ enable_mapgen_debug_info(false),
+ id(ethreadid),
+ m_server(server),
+ m_map(NULL),
+ m_emerge(NULL),
+ m_mapgen(NULL)
+{
+ m_name = "Emerge-" + itos(ethreadid);
+}
+
+
+EmergeThread::~EmergeThread()
+{
+ //cancelPendingItems();
+}
+
+
+void EmergeThread::signal()
+{
+ m_queue_event.signal();
+}
+
+
+bool EmergeThread::pushBlock(v3s16 pos)
+{
+ m_block_queue.push(pos);
+ return true;
+}
+
+
+void EmergeThread::cancelPendingItems()
+{
+ MutexAutoLock queuelock(m_emerge->m_queue_mutex);
+
+ while (!m_block_queue.empty()) {
+ BlockEmergeData bedata;
+ v3s16 pos;
+
+ pos = m_block_queue.front();
+ m_block_queue.pop();
+
+ m_emerge->popBlockEmergeData(pos, &bedata);
+
+ runCompletionCallbacks(pos, EMERGE_CANCELLED, bedata.callbacks);
+ }
+}
+
+
+void EmergeThread::runCompletionCallbacks(
+ v3s16 pos,
+ EmergeAction action,
+ const EmergeCallbackList &callbacks)
+{
+ for (size_t i = 0; i != callbacks.size(); i++) {
+ EmergeCompletionCallback callback;
+ void *param;
+
+ callback = callbacks[i].first;
+ param = callbacks[i].second;
+
+ callback(pos, action, param);
+ }
+}
+