Skip to content

Commit

Permalink
Isolate interrupt requests to single thread
Browse files Browse the repository at this point in the history
  • Loading branch information
dbaston committed Dec 7, 2022
1 parent 9af6077 commit d6413ef
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 4 deletions.
6 changes: 2 additions & 4 deletions src/util/Interrupt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@
#include <geos/util/GEOSException.h> // for inheritance

namespace {
/* Could these be portably stored in thread-specific space ? */
bool requested = false;

geos::util::Interrupt::Callback* callback = nullptr;
thread_local bool requested = false;
thread_local geos::util::Interrupt::Callback* callback = nullptr;
}

namespace geos {
Expand Down
50 changes: 50 additions & 0 deletions tests/unit/capi/GEOSInterruptTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <cstdio>
#include <cstdlib>
#include <memory>
#include <thread>

namespace tut {
//
Expand All @@ -18,6 +19,7 @@ namespace tut {
// Common data used in test cases.
struct test_capiinterrupt_data {
static int numcalls;
static int numcalls2;
static GEOSInterruptCallback* nextcb;

static void
Expand Down Expand Up @@ -56,9 +58,19 @@ struct test_capiinterrupt_data {
}
}

static void
countCalls2()
{
++numcalls2;
if(nextcb) {
(*nextcb)();
}
}

};

int test_capiinterrupt_data::numcalls = 0;
int test_capiinterrupt_data::numcalls2 = 0;
GEOSInterruptCallback* test_capiinterrupt_data::nextcb = nullptr;

typedef test_group<test_capiinterrupt_data> group;
Expand Down Expand Up @@ -221,5 +233,43 @@ void object::test<5>
}


// Test callback is thread-local
template<>
template<>
void object::test<6>
()
{
numcalls = 0;
numcalls2 = 0;
nextcb = nullptr;

initGEOS(notice, notice);

auto buffer = [](GEOSInterruptCallback* cb) {
GEOSGeometry* geom1 = GEOSGeomFromWKT("LINESTRING (0 0, 1 0)");

GEOS_interruptRegisterCallback(cb);

GEOSGeometry* geom2 = GEOSBuffer(geom1, 1, 8);
GEOSGeom_destroy(geom2);
GEOSGeom_destroy(geom1);

GEOS_interruptRegisterCallback(nullptr);
};

std::thread t1(buffer, countCalls);
std::thread t2(buffer, countCalls2);

t1.join();
t2.join();

ensure("numcalls > 0", numcalls > 0);
ensure("numcalls2 > 0", numcalls2 > 0);
ensure_equals(numcalls, numcalls2);

finishGEOS();
}


} // namespace tut

0 comments on commit d6413ef

Please sign in to comment.