Skip to content

Commit 9a74c4c

Browse files
committed
viewer: Use std::unique_ptr in waiting_for_events data structure
The current usage of waiting_for_events is taking ownership of SVEvent pointer from a unique_ptr. This is error prone as all code paths using waiting_for_events need to ensure deletion. We fix it by using unique_ptr in waiting_for_events and all dependent code paths.
1 parent 4f831ff commit 9a74c4c

File tree

9 files changed

+21
-32
lines changed

9 files changed

+21
-32
lines changed

src/classify/intproto.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,12 +1163,11 @@ void FillPPLinearBits(uint32_t ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR],
11631163
CLASS_ID Classify::GetClassToDebug(const char *Prompt, bool *adaptive_on, bool *pretrained_on,
11641164
int *shape_id) {
11651165
tprintf("%s\n", Prompt);
1166-
SVEvent *ev;
11671166
SVEventType ev_type;
11681167
int unichar_id = INVALID_UNICHAR_ID;
11691168
// Wait until a click or popup event.
11701169
do {
1171-
ev = IntMatchWindow->AwaitEvent(SVET_ANY);
1170+
auto ev = IntMatchWindow->AwaitEvent(SVET_ANY);
11721171
ev_type = ev->type;
11731172
if (ev_type == SVET_POPUP) {
11741173
if (ev->command_id == IDA_SHAPE_INDEX) {
@@ -1214,7 +1213,6 @@ CLASS_ID Classify::GetClassToDebug(const char *Prompt, bool *adaptive_on, bool *
12141213
}
12151214
}
12161215
}
1217-
delete ev;
12181216
} while (ev_type != SVET_CLICK);
12191217
return 0;
12201218
} /* GetClassToDebug */

src/classify/shapeclassifier.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ void ShapeClassifier::DebugDisplay(const TrainingSample &sample, Image page_pix,
115115
std::vector<UnicharRating> results;
116116
// Debug classification until the user quits.
117117
const UNICHARSET &unicharset = GetUnicharset();
118-
SVEvent *ev;
119118
SVEventType ev_type;
120119
do {
121120
std::vector<ScrollView *> windows;
@@ -135,7 +134,7 @@ void ShapeClassifier::DebugDisplay(const TrainingSample &sample, Image page_pix,
135134
UNICHAR_ID old_unichar_id;
136135
do {
137136
old_unichar_id = unichar_id;
138-
ev = debug_win->AwaitEvent(SVET_ANY);
137+
auto ev = debug_win->AwaitEvent(SVET_ANY);
139138
ev_type = ev->type;
140139
if (ev_type == SVET_POPUP) {
141140
if (unicharset.contains_unichar(ev->parameter)) {
@@ -144,7 +143,6 @@ void ShapeClassifier::DebugDisplay(const TrainingSample &sample, Image page_pix,
144143
tprintf("Char class '%s' not found in unicharset", ev->parameter);
145144
}
146145
}
147-
delete ev;
148146
} while (unichar_id == old_unichar_id && ev_type != SVET_CLICK && ev_type != SVET_DESTROY);
149147
for (auto window : windows) {
150148
delete window;

src/textord/ccnontextdetect.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ Image CCNonTextDetect::ComputeNonTextMask(bool debug, Image photo_map, TO_BLOCK
134134
#endif // !GRAPHICS_DISABLED
135135
pixWrite("junkccphotomask.png", pix, IFF_PNG);
136136
#ifndef GRAPHICS_DISABLED
137-
delete win->AwaitEvent(SVET_DESTROY);
137+
win->AwaitEvent(SVET_DESTROY);
138138
delete win;
139139
#endif // !GRAPHICS_DISABLED
140140
}

src/textord/colfind.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ int ColumnFinder::FindBlocks(PageSegMode pageseg_mode, Image scaled_color, int s
440440
DisplayTabVectors(window);
441441
}
442442
if (window != nullptr && textord_tabfind_show_partitions > 1) {
443-
delete window->AwaitEvent(SVET_DESTROY);
443+
window->AwaitEvent(SVET_DESTROY);
444444
}
445445
}
446446
}
@@ -476,7 +476,7 @@ int ColumnFinder::FindBlocks(PageSegMode pageseg_mode, Image scaled_color, int s
476476
bool waiting = false;
477477
do {
478478
waiting = false;
479-
SVEvent *event = blocks_win_->AwaitEvent(SVET_ANY);
479+
auto event = blocks_win_->AwaitEvent(SVET_ANY);
480480
if (event->type == SVET_INPUT && event->parameter != nullptr) {
481481
if (*event->parameter == 'd') {
482482
result = -1;
@@ -488,7 +488,6 @@ int ColumnFinder::FindBlocks(PageSegMode pageseg_mode, Image scaled_color, int s
488488
} else {
489489
waiting = true;
490490
}
491-
delete event;
492491
} while (waiting);
493492
}
494493
#endif // !GRAPHICS_DISABLED

src/textord/strokewidth.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ StrokeWidth::StrokeWidth(int gridsize, const ICOORD &bleft, const ICOORD &tright
123123
StrokeWidth::~StrokeWidth() {
124124
#ifndef GRAPHICS_DISABLED
125125
if (widths_win_ != nullptr) {
126-
delete widths_win_->AwaitEvent(SVET_DESTROY);
126+
widths_win_->AwaitEvent(SVET_DESTROY);
127127
if (textord_tabfind_only_strokewidths) {
128128
exit(0);
129129
}

src/training/common/mastertrainer.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -785,9 +785,8 @@ void MasterTrainer::DisplaySamples(const char *unichar_str1, int cloud_font,
785785
ScrollView *s_window = CreateFeatureSpaceWindow("Samples", 100, 500);
786786
SVEventType ev_type;
787787
do {
788-
SVEvent *ev;
789788
// Wait until a click or popup event.
790-
ev = f_window->AwaitEvent(SVET_ANY);
789+
auto ev = f_window->AwaitEvent(SVET_ANY);
791790
ev_type = ev->type;
792791
if (ev_type == SVET_CLICK) {
793792
int feature_index = feature_space.XYToFeatureIndex(ev->x, ev->y);
@@ -801,7 +800,6 @@ void MasterTrainer::DisplaySamples(const char *unichar_str1, int cloud_font,
801800
s_window->Update();
802801
}
803802
}
804-
delete ev;
805803
} while (ev_type != SVET_DESTROY);
806804
}
807805
#endif // !GRAPHICS_DISABLED

src/training/unicharset/lstmtrainer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -891,7 +891,7 @@ Trainability LSTMTrainer::TrainOnLine(const ImageData *trainingdata,
891891
}
892892
#ifndef GRAPHICS_DISABLED
893893
if (debug_interval_ == 1 && debug_win_ != nullptr) {
894-
delete debug_win_->AwaitEvent(SVET_CLICK);
894+
debug_win_->AwaitEvent(SVET_CLICK);
895895
}
896896
#endif // !GRAPHICS_DISABLED
897897
// Roll the memory of past means.

src/viewer/scrollview.cpp

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ struct SVPolyLineBuffer {
5656
static std::map<int, ScrollView *> svmap;
5757
static std::mutex *svmap_mu;
5858
// A map of all semaphores waiting for a specific event on a specific window.
59-
static std::map<std::pair<ScrollView *, SVEventType>, std::pair<SVSemaphore *, SVEvent *>>
60-
waiting_for_events;
59+
static std::map<std::pair<ScrollView *, SVEventType>,
60+
std::pair<SVSemaphore *, std::unique_ptr<SVEvent>>> waiting_for_events;
6161
static std::mutex *waiting_for_events_mu;
6262

6363
SVEvent *SVEvent::copy() const {
@@ -158,13 +158,13 @@ void ScrollView::MessageReceiver() {
158158
SVET_ANY);
159159
waiting_for_events_mu->lock();
160160
if (waiting_for_events.count(awaiting_list) > 0) {
161-
waiting_for_events[awaiting_list].second = cur.release();
161+
waiting_for_events[awaiting_list].second = std::move(cur);
162162
waiting_for_events[awaiting_list].first->Signal();
163163
} else if (waiting_for_events.count(awaiting_list_any) > 0) {
164-
waiting_for_events[awaiting_list_any].second = cur.release();
164+
waiting_for_events[awaiting_list_any].second = std::move(cur);
165165
waiting_for_events[awaiting_list_any].first->Signal();
166166
} else if (waiting_for_events.count(awaiting_list_any_window) > 0) {
167-
waiting_for_events[awaiting_list_any_window].second = cur.release();
167+
waiting_for_events[awaiting_list_any_window].second = std::move(cur);
168168
waiting_for_events[awaiting_list_any_window].first->Signal();
169169
}
170170
waiting_for_events_mu->unlock();
@@ -367,8 +367,7 @@ ScrollView::~ScrollView() {
367367
// So the event handling thread can quit.
368368
SendMsg("destroy()");
369369

370-
SVEvent *sve = AwaitEvent(SVET_DESTROY);
371-
delete sve;
370+
AwaitEvent(SVET_DESTROY);
372371
svmap_mu->lock();
373372
svmap[window_id_] = nullptr;
374373
svmap_mu->unlock();
@@ -442,19 +441,19 @@ void ScrollView::SetEvent(const SVEvent *svevent) {
442441
/// Block until an event of the given type is received.
443442
/// Note: The calling function is responsible for deleting the returned
444443
/// SVEvent afterwards!
445-
SVEvent *ScrollView::AwaitEvent(SVEventType type) {
444+
std::unique_ptr<SVEvent> ScrollView::AwaitEvent(SVEventType type) {
446445
// Initialize the waiting semaphore.
447446
auto *sem = new SVSemaphore();
448447
std::pair<ScrollView *, SVEventType> ea(this, type);
449448
waiting_for_events_mu->lock();
450-
waiting_for_events[ea] = std::pair<SVSemaphore *, SVEvent *>(sem, (SVEvent *)nullptr);
449+
waiting_for_events[ea] = {sem, nullptr};
451450
waiting_for_events_mu->unlock();
452451
// Wait on it, but first flush.
453452
stream_->Flush();
454453
sem->Wait();
455454
// Process the event we got woken up for (its in waiting_for_events pair).
456455
waiting_for_events_mu->lock();
457-
SVEvent *ret = waiting_for_events[ea].second;
456+
auto ret = std::move(waiting_for_events[ea].second);
458457
waiting_for_events.erase(ea);
459458
delete sem;
460459
waiting_for_events_mu->unlock();
@@ -734,23 +733,19 @@ void ScrollView::Brush(Color color) {
734733
// Shows a modal Input Dialog which can return any kind of String
735734
char *ScrollView::ShowInputDialog(const char *msg) {
736735
SendMsg("showInputDialog(\"%s\")", msg);
737-
SVEvent *ev;
738736
// wait till an input event (all others are thrown away)
739-
ev = AwaitEvent(SVET_INPUT);
737+
auto ev = AwaitEvent(SVET_INPUT);
740738
char *p = new char[strlen(ev->parameter) + 1];
741739
strcpy(p, ev->parameter);
742-
delete ev;
743740
return p;
744741
}
745742

746743
// Shows a modal Yes/No Dialog which will return 'y' or 'n'
747744
int ScrollView::ShowYesNoDialog(const char *msg) {
748745
SendMsg("showYesNoDialog(\"%s\")", msg);
749-
SVEvent *ev;
750746
// Wait till an input event (all others are thrown away)
751-
ev = AwaitEvent(SVET_INPUT);
747+
auto ev = AwaitEvent(SVET_INPUT);
752748
int a = ev->parameter[0];
753-
delete ev;
754749
return a;
755750
}
756751

src/viewer/scrollview.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <tesseract/export.h>
3737

3838
#include <cstdio>
39+
#include <memory>
3940
#include <mutex>
4041

4142
namespace tesseract {
@@ -186,7 +187,7 @@ class TESS_API ScrollView {
186187
void AddEventHandler(SVEventHandler *listener);
187188

188189
// Block until an event of the given type is received.
189-
SVEvent *AwaitEvent(SVEventType type);
190+
std::unique_ptr<SVEvent> AwaitEvent(SVEventType type);
190191

191192
/*******************************************************************************
192193
* Getters and Setters

0 commit comments

Comments
 (0)