mirror of
https://github.com/tesseract-ocr/tesseract.git
synced 2024-12-05 02:47:00 +08:00
Merge pull request #2569 from stweil/thread
Replace propriatary thread data type by std::thread
This commit is contained in:
commit
852dbe3530
@ -24,11 +24,7 @@
|
||||
#include "imagedata.h"
|
||||
|
||||
#include <cinttypes> // for PRId64
|
||||
#if defined(__MINGW32__)
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <thread>
|
||||
#endif
|
||||
#include <thread> // for std::thread
|
||||
|
||||
#include "allheaders.h" // for pixDestroy, pixGetHeight, pixGetWidth, lept_...
|
||||
#include "boxread.h" // for ReadMemBoxes
|
||||
@ -374,13 +370,6 @@ bool ImageData::AddBoxes(const char* box_text) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Thread function to call ReCachePages.
|
||||
void* ReCachePagesFunc(void* data) {
|
||||
auto* document_data = static_cast<DocumentData*>(data);
|
||||
document_data->ReCachePages();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DocumentData::DocumentData(const STRING& name)
|
||||
: document_name_(name),
|
||||
pages_offset_(-1),
|
||||
@ -448,7 +437,8 @@ void DocumentData::LoadPageInBackground(int index) {
|
||||
if (pages_offset_ == index) return;
|
||||
pages_offset_ = index;
|
||||
pages_.clear();
|
||||
SVSync::StartThread(ReCachePagesFunc, this);
|
||||
std::thread t(&tesseract::DocumentData::ReCachePages, this);
|
||||
t.detach();
|
||||
}
|
||||
|
||||
// Returns a pointer to the page with the given index, modulo the total
|
||||
@ -463,11 +453,7 @@ const ImageData* DocumentData::GetPage(int index) {
|
||||
if (needs_loading) LoadPageInBackground(index);
|
||||
// We can't directly load the page, or the background load will delete it
|
||||
// while the caller is using it, so give it a chance to work.
|
||||
#if defined(__MINGW32__)
|
||||
sleep(1);
|
||||
#else
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
#endif
|
||||
std::this_thread::yield();
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
// File: lstmtester.cpp
|
||||
// Description: Top-level line evaluation class for LSTM-based networks.
|
||||
// Author: Ray Smith
|
||||
// Created: Wed Nov 23 11:18:06 PST 2016
|
||||
//
|
||||
// (C) Copyright 2016, Google Inc.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -16,6 +15,7 @@
|
||||
// limitations under the License.
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <thread> // for std::thread
|
||||
#include "lstmtester.h"
|
||||
#include "genericvector.h"
|
||||
|
||||
@ -70,7 +70,8 @@ STRING LSTMTester::RunEvalAsync(int iteration, const double* training_errors,
|
||||
test_training_errors_ = training_errors;
|
||||
test_model_mgr_ = model_mgr;
|
||||
test_training_stage_ = training_stage;
|
||||
SVSync::StartThread(&LSTMTester::ThreadFunc, this);
|
||||
std::thread t(&LSTMTester::ThreadFunc, this);
|
||||
t.detach();
|
||||
} else {
|
||||
UnlockRunning();
|
||||
}
|
||||
@ -123,21 +124,15 @@ STRING LSTMTester::RunEvalSync(int iteration, const double* training_errors,
|
||||
return result;
|
||||
}
|
||||
|
||||
// Static helper thread function for RunEvalAsync, with a specific signature
|
||||
// required by SVSync::StartThread. Actually a member function pretending to
|
||||
// be static, its arg is a this pointer that it will cast back to LSTMTester*
|
||||
// to call RunEvalSync using the stored args that RunEvalAsync saves in *this.
|
||||
// Helper thread function for RunEvalAsync.
|
||||
// LockIfNotRunning must have returned true before calling ThreadFunc, and
|
||||
// it will call UnlockRunning to release the lock after RunEvalSync completes.
|
||||
/* static */
|
||||
void* LSTMTester::ThreadFunc(void* lstmtester_void) {
|
||||
LSTMTester* lstmtester = static_cast<LSTMTester*>(lstmtester_void);
|
||||
lstmtester->test_result_ = lstmtester->RunEvalSync(
|
||||
lstmtester->test_iteration_, lstmtester->test_training_errors_,
|
||||
lstmtester->test_model_mgr_, lstmtester->test_training_stage_,
|
||||
void LSTMTester::ThreadFunc() {
|
||||
test_result_ = RunEvalSync(
|
||||
test_iteration_, test_training_errors_,
|
||||
test_model_mgr_, test_training_stage_,
|
||||
/*verbosity*/ 0);
|
||||
lstmtester->UnlockRunning();
|
||||
return lstmtester_void;
|
||||
UnlockRunning();
|
||||
}
|
||||
|
||||
// Returns true if there is currently nothing running, and takes the lock
|
||||
|
@ -62,13 +62,10 @@ class LSTMTester {
|
||||
int verbosity);
|
||||
|
||||
private:
|
||||
// Static helper thread function for RunEvalAsync, with a specific signature
|
||||
// required by SVSync::StartThread. Actually a member function pretending to
|
||||
// be static, its arg is a this pointer that it will cast back to LSTMTester*
|
||||
// to call RunEvalSync using the stored args that RunEvalAsync saves in *this.
|
||||
// Helper thread function for RunEvalAsync.
|
||||
// LockIfNotRunning must have returned true before calling ThreadFunc, and
|
||||
// it will call UnlockRunning to release the lock after RunEvalSync completes.
|
||||
static void* ThreadFunc(void* lstmtester_void);
|
||||
void ThreadFunc();
|
||||
// Returns true if there is currently nothing running, and takes the lock
|
||||
// if there is nothing running.
|
||||
bool LockIfNotRunning();
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <map>
|
||||
#include <mutex> // for std::mutex
|
||||
#include <string>
|
||||
#include <thread> // for std::thread
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@ -80,7 +81,7 @@ SVEventHandler::~SVEventHandler() = default;
|
||||
/// to the client. It basically loops through messages, parses them to events
|
||||
/// and distributes it to the waiting handlers.
|
||||
/// It is run from a different thread and synchronizes via SVSync.
|
||||
void* ScrollView::MessageReceiver(void* a) {
|
||||
void ScrollView::MessageReceiver() {
|
||||
int counter_event_id = 0; // ongoing counter
|
||||
char* message = nullptr;
|
||||
// Wait until a new message appears in the input stream_.
|
||||
@ -177,7 +178,6 @@ void* ScrollView::MessageReceiver(void* a) {
|
||||
message = ScrollView::GetStream()->Receive();
|
||||
} while (message == nullptr);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Table to implement the color index values in the old system.
|
||||
@ -277,7 +277,8 @@ void ScrollView::Initialize(const char* name, int x_pos, int y_pos, int x_size,
|
||||
svmap_mu = new std::mutex();
|
||||
SendRawMessage(
|
||||
"svmain = luajava.bindClass('com.google.scrollview.ScrollView')\n");
|
||||
SVSync::StartThread(MessageReceiver, nullptr);
|
||||
std::thread t(&ScrollView::MessageReceiver);
|
||||
t.detach();
|
||||
}
|
||||
|
||||
// Set up the variables on the clientside.
|
||||
@ -312,48 +313,48 @@ void ScrollView::Initialize(const char* name, int x_pos, int y_pos, int x_size,
|
||||
x_pos, y_pos, x_size, y_size, x_canvas_size, y_canvas_size);
|
||||
SendRawMessage(message);
|
||||
|
||||
SVSync::StartThread(StartEventHandler, this);
|
||||
std::thread t(&ScrollView::StartEventHandler, this);
|
||||
t.detach();
|
||||
}
|
||||
|
||||
/// Sits and waits for events on this window.
|
||||
void* ScrollView::StartEventHandler(void* a) {
|
||||
auto* sv = static_cast<ScrollView*>(a);
|
||||
void ScrollView::StartEventHandler() {
|
||||
SVEvent* new_event;
|
||||
|
||||
do {
|
||||
for (;;) {
|
||||
stream_->Flush();
|
||||
sv->semaphore_->Wait();
|
||||
semaphore_->Wait();
|
||||
new_event = nullptr;
|
||||
int serial = -1;
|
||||
int k = -1;
|
||||
sv->mutex_->lock();
|
||||
mutex_->lock();
|
||||
// Check every table entry if he is is valid and not already processed.
|
||||
|
||||
for (int i = 0; i < SVET_COUNT; i++) {
|
||||
if (sv->event_table_[i] != nullptr &&
|
||||
(serial < 0 || sv->event_table_[i]->counter < serial)) {
|
||||
new_event = sv->event_table_[i];
|
||||
serial = sv->event_table_[i]->counter;
|
||||
if (event_table_[i] != nullptr &&
|
||||
(serial < 0 || event_table_[i]->counter < serial)) {
|
||||
new_event = event_table_[i];
|
||||
serial = event_table_[i]->counter;
|
||||
k = i;
|
||||
}
|
||||
}
|
||||
// If we didn't find anything we had an old alarm and just sleep again.
|
||||
if (new_event != nullptr) {
|
||||
sv->event_table_[k] = nullptr;
|
||||
sv->mutex_->unlock();
|
||||
if (sv->event_handler_ != nullptr) { sv->event_handler_->Notify(new_event); }
|
||||
event_table_[k] = nullptr;
|
||||
mutex_->unlock();
|
||||
if (event_handler_ != nullptr) { event_handler_->Notify(new_event); }
|
||||
if (new_event->type == SVET_DESTROY) {
|
||||
// Signal the destructor that it is safe to terminate.
|
||||
sv->event_handler_ended_ = true;
|
||||
sv = nullptr;
|
||||
event_handler_ended_ = true;
|
||||
delete new_event; // Delete the pointer after it has been processed.
|
||||
return;
|
||||
}
|
||||
delete new_event; // Delete the pointer after it has been processed.
|
||||
} else {
|
||||
sv->mutex_->unlock();
|
||||
mutex_->unlock();
|
||||
}
|
||||
// The thread should run as long as its associated window is alive.
|
||||
} while (sv != nullptr);
|
||||
return nullptr;
|
||||
// The thread should run as long as its associated window is alive.
|
||||
}
|
||||
}
|
||||
#endif // GRAPHICS_DISABLED
|
||||
|
||||
|
@ -361,8 +361,8 @@ class ScrollView {
|
||||
// Send the current buffered polygon (if any) and clear it.
|
||||
void SendPolygon();
|
||||
|
||||
// Start the message receiving thread.
|
||||
static void* MessageReceiver(void* a);
|
||||
// Start the message receiving thread.
|
||||
static void MessageReceiver();
|
||||
|
||||
// Place an event into the event_table (synchronized).
|
||||
void SetEvent(SVEvent* svevent);
|
||||
@ -373,8 +373,9 @@ class ScrollView {
|
||||
// Returns the unique, shared network stream.
|
||||
static SVNetwork* GetStream() { return stream_; }
|
||||
|
||||
// Starts a new event handler. Called whenever a new window is created.
|
||||
static void* StartEventHandler(void* sv);
|
||||
// Starts a new event handler.
|
||||
// Called asynchronously whenever a new window is created.
|
||||
void StartEventHandler();
|
||||
|
||||
// Escapes the ' character with a \, so it can be processed by LUA.
|
||||
char* AddEscapeChars(const char* input);
|
||||
|
@ -41,7 +41,6 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <csignal>
|
||||
#include <sys/select.h>
|
||||
@ -52,39 +51,10 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
// Create new thread.
|
||||
void SVSync::StartThread(void* (*func)(void*), void* arg) {
|
||||
#ifdef _WIN32
|
||||
LPTHREAD_START_ROUTINE f = (LPTHREAD_START_ROUTINE)func;
|
||||
DWORD threadid;
|
||||
CreateThread(nullptr, // default security attributes
|
||||
0, // use default stack size
|
||||
f, // thread function
|
||||
arg, // argument to thread function
|
||||
0, // use default creation flags
|
||||
&threadid); // returns the thread identifier
|
||||
#else
|
||||
pthread_t helper;
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
pthread_create(&helper, &attr, func, arg);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef GRAPHICS_DISABLED
|
||||
|
||||
const int kMaxMsgSize = 4096;
|
||||
|
||||
// Signals a thread to exit.
|
||||
void SVSync::ExitThread() {
|
||||
#ifdef _WIN32
|
||||
// ExitThread(0);
|
||||
#else
|
||||
pthread_exit(nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Starts a new process.
|
||||
void SVSync::StartProcess(const char* executable, const char* args) {
|
||||
std::string proc;
|
||||
|
@ -26,7 +26,6 @@
|
||||
#ifdef _WIN32
|
||||
# include "host.h" // also includes windows.h
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#endif
|
||||
|
||||
@ -36,10 +35,6 @@
|
||||
/// The SVSync class provides functionality for Thread & Process Creation
|
||||
class SVSync {
|
||||
public:
|
||||
/// Create new thread.
|
||||
static void StartThread(void *(*func)(void*), void* arg);
|
||||
/// Signals a thread to exit.
|
||||
static void ExitThread();
|
||||
/// Starts a new process.
|
||||
static void StartProcess(const char* executable, const char* args);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user