From f75eb0307c989890c72ca4cbbe69ce06022a8cef Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Tue, 21 Oct 2014 10:08:54 +0000 Subject: [PATCH] Add interruptability API to liblwgeom git-svn-id: http://svn.osgeo.org/postgis/trunk@13099 b70326c6-7e19-0410-871a-916f4a2858ee --- NEWS | 1 + liblwgeom/liblwgeom.h.in | 27 +++++++++++++++++++++++++++ liblwgeom/liblwgeom_internal.h | 13 +++++++++++++ liblwgeom/lwgeom_api.c | 12 ++++++++++++ postgis/postgis_module.c | 10 +++++----- 5 files changed, 58 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 4b35d1127..060831111 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,7 @@ PostGIS 2.2.0 * New Features * + - Interruptibility API for liblwgeom (Sandro Santilli / CartoDB) - #2939, ST_ClipByBox2D (Sandro Santilli / CartoDB) - #2247, ST_Retile and ST_CreateOverview: in-db raster overviews creation (Sandro Santilli / Vizzuality) diff --git a/liblwgeom/liblwgeom.h.in b/liblwgeom/liblwgeom.h.in index 68233070b..f3da1c473 100644 --- a/liblwgeom/liblwgeom.h.in +++ b/liblwgeom/liblwgeom.h.in @@ -189,6 +189,33 @@ extern void lwgeom_set_handlers(lwallocator allocator, lwreallocator reallocator, lwfreeor freeor, lwreporter errorreporter, lwreporter noticereporter); +/** + * Request interruption of any running code + * + * Safe for use from signal handlers + * + * Interrupted code will (as soon as it finds out + * to be interrupted) cleanup and return as soon as possible. + * + * The return value from interrupted code is undefined, + * it is the caller responsibility to not take it in consideration. + * + */ +extern void lwgeom_request_interrupt(void); + +/** + * Install a callback to be called periodically during + * algorithm execution. Mostly only needed on WIN32 to + * dispatch queued signals. + * + * The callback is invoked before checking for interrupt + * being requested, so you can request interruption from + * the callback, if you want (see lwgeom_request_interrupt). + * + */ +typedef void (lwinterrupt_callback)(); +extern lwinterrupt_callback *lwgeom_register_interrupt_callback(lwinterrupt_callback *); + /** * Write a notice out to the notice handler. * diff --git a/liblwgeom/liblwgeom_internal.h b/liblwgeom/liblwgeom_internal.h index 61a747cd5..77eb6dcb4 100644 --- a/liblwgeom/liblwgeom_internal.h +++ b/liblwgeom/liblwgeom_internal.h @@ -405,4 +405,17 @@ extern void trim_trailing_zeros(char *num); extern uint8_t MULTITYPE[NUMTYPES]; +extern lwinterrupt_callback *_lwgeom_interrupt_callback; +extern int _lwgeom_interrupt_requested; +#define LW_ON_INTERRUPT(x) { \ + if ( _lwgeom_interrupt_callback ) { \ + (*_lwgeom_interrupt_callback)(); \ + } \ + if ( _lwgeom_interrupt_requested ) { \ + _lwgeom_interrupt_requested = 0; \ + lwnotice("liblwgeom code interrupted"); \ + x; \ + } \ +} + #endif /* _LIBLWGEOM_INTERNAL_H */ diff --git a/liblwgeom/lwgeom_api.c b/liblwgeom/lwgeom_api.c index 3323e0949..7ae2a9c75 100644 --- a/liblwgeom/lwgeom_api.c +++ b/liblwgeom/lwgeom_api.c @@ -762,4 +762,16 @@ interpolate_point4d(POINT4D *A, POINT4D *B, POINT4D *I, double F) } +int _lwgeom_interrupt_requested = 0; +void +lwgeom_request_interrupt() { + _lwgeom_interrupt_requested = 1; +} +lwinterrupt_callback *_lwgeom_interrupt_callback = 0; +lwinterrupt_callback * +lwgeom_register_interrupt_callback(lwinterrupt_callback *cb) { + lwinterrupt_callback *old = _lwgeom_interrupt_callback; + _lwgeom_interrupt_callback = cb; + return old; +} diff --git a/postgis/postgis_module.c b/postgis/postgis_module.c index cefb7d408..c787e39d1 100644 --- a/postgis/postgis_module.c +++ b/postgis/postgis_module.c @@ -32,13 +32,11 @@ static pqsigfunc coreIntHandler = 0; static void handleInterrupt(int sig); #ifdef WIN32 -#if POSTGIS_GEOS_VERSION >= 34 -static void geosInterruptCallback() { +static void interruptCallback() { if (UNBLOCKED_SIGNAL_QUEUE()) pgwin32_dispatch_queued_signals(); } #endif -#endif /* * Module load callback @@ -52,8 +50,9 @@ _PG_init(void) #ifdef WIN32 #if POSTGIS_GEOS_VERSION >= 34 - GEOS_interruptRegisterCallback(geosInterruptCallback); + GEOS_interruptRegisterCallback(interruptCallback); #endif + lwgeom_register_interrupt_callback(interruptCallback); #endif #if 0 @@ -120,7 +119,8 @@ handleInterrupt(int sig) GEOS_interruptRequest(); #endif - /* TODO: request interruption of liblwgeom as well ? */ + /* request interruption of liblwgeom as well */ + lwgeom_request_interrupt(); if ( coreIntHandler ) { (*coreIntHandler)(sig); -- 2.50.1