Michael Uleysky
9 years ago
3 changed files with 118 additions and 0 deletions
@ -0,0 +1,86 @@ |
|||||||
|
#include "modgmt.h" |
||||||
|
|
||||||
|
#if defined MODGMT_WORKAROUND_EXIT |
||||||
|
// Exit handler.
|
||||||
|
static void gmtonexithandler(int ret, void* x) |
||||||
|
{ |
||||||
|
reinterpret_cast<struct gmtworkthreadpars*>(x)->ret=ret; |
||||||
|
close(reinterpret_cast<struct gmtworkthreadpars*>(x)->fd); |
||||||
|
pthread_exit(&(reinterpret_cast<struct gmtworkthreadpars*>(x)->ret)); |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
// This function call GMT_Call_Module in separate thread. It just a hack to workaround absence of callbacks.
|
||||||
|
static void* gmtworkthread(void* x) |
||||||
|
{ |
||||||
|
struct gmtworkthreadpars* p=reinterpret_cast<struct gmtworkthreadpars*>(x); |
||||||
|
#if defined MODGMT_WORKAROUND_EXIT |
||||||
|
on_exit(gmtonexithandler,x); |
||||||
|
#endif |
||||||
|
GMT_Append_Option(p->api,GMT_Make_Option(p->api,'>',const_cast<char*>(("/dev/fd/"+std::to_string(p->fd)).c_str())),p->opts); |
||||||
|
p->ret=GMT_Call_Module(p->api,p->module,GMT_MODULE_OPT,p->opts); |
||||||
|
#if defined MODGMT_WORKAROUND_EXIT |
||||||
|
exit(p->ret); |
||||||
|
#endif |
||||||
|
close(p->fd); |
||||||
|
return &p->ret; |
||||||
|
} |
||||||
|
|
||||||
|
// Wrapper for GMT_Call_Module, res is output.
|
||||||
|
int callgmtmodule(void *api, const char *module, struct GMT_OPTION *opts, std::string& res) |
||||||
|
{ |
||||||
|
int pipefd[2]; |
||||||
|
ssize_t br; |
||||||
|
char buffer[4096]; |
||||||
|
pthread_t wthr; |
||||||
|
struct gmtworkthreadpars p; |
||||||
|
int *pret; |
||||||
|
|
||||||
|
pipe(pipefd); |
||||||
|
p.api=api; |
||||||
|
p.module=module; |
||||||
|
p.opts=opts; |
||||||
|
p.fd=pipefd[1]; |
||||||
|
|
||||||
|
pthread_create(&wthr,0,&gmtworkthread,&p); |
||||||
|
|
||||||
|
res.erase(); |
||||||
|
do |
||||||
|
{ |
||||||
|
br=read(pipefd[0],buffer,4096); |
||||||
|
res.append(buffer,br); |
||||||
|
} while(0!=br); |
||||||
|
close(pipefd[0]); |
||||||
|
res.shrink_to_fit(); |
||||||
|
pthread_join(wthr,reinterpret_cast<void**>(&pret)); |
||||||
|
|
||||||
|
return *pret; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
// Initialisation function
|
||||||
|
int gmt_module_init(void* p) |
||||||
|
{ |
||||||
|
// Fill header and footer
|
||||||
|
struct GMT_OPTION* opts; |
||||||
|
void* gmtapi; |
||||||
|
int ret; |
||||||
|
const char* ch="--GMT_HISTORY=f -C -P -K"; |
||||||
|
const char* cf="--GMT_HISTORY=f -C -P -O"; |
||||||
|
char* h=strdup(ch); |
||||||
|
char* f=strdup(cf); |
||||||
|
|
||||||
|
gmtapi=GMT_Create_Session("gmt_makemap",2,3,0); |
||||||
|
if(0==gmtapi) return 1; |
||||||
|
opts=GMT_Create_Options(gmtapi,0,h); |
||||||
|
ret=callgmtmodule(gmtapi,"psclip",opts,header); |
||||||
|
GMT_Destroy_Options(gmtapi,&opts); |
||||||
|
opts=GMT_Create_Options(gmtapi,0,f); |
||||||
|
if(0==ret) ret=callgmtmodule(gmtapi,"psclip",opts,footer); |
||||||
|
GMT_Destroy_Options(gmtapi,&opts); |
||||||
|
GMT_Destroy_Session(gmtapi); |
||||||
|
free(h); free(f); |
||||||
|
if(0!=ret) return ret; |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
#include <pthread.h> |
||||||
|
#include <unistd.h> |
||||||
|
#include <gmt.h> |
||||||
|
#include <string.h> |
||||||
|
#include "common.h" |
||||||
|
|
||||||
|
// Workaround exit() in GMT_Call_Module. May need because return mode of gmt api is not very reliable
|
||||||
|
#if defined MODGMT_WORKAROUND_EXIT |
||||||
|
#define GMTMODE 0 |
||||||
|
#else |
||||||
|
#define GMTMODE 3 |
||||||
|
#endif |
||||||
|
|
||||||
|
// here we save header and footer of gmt-produced eps files
|
||||||
|
std::string header,footer; |
||||||
|
|
||||||
|
// Parameters for working thread
|
||||||
|
struct gmtworkthreadpars |
||||||
|
{ |
||||||
|
void* api; |
||||||
|
const char* module; |
||||||
|
struct GMT_OPTION* opts; |
||||||
|
int fd; |
||||||
|
int ret; |
||||||
|
}; |
||||||
|
|
||||||
|
extern "C" { |
||||||
|
EXPORT int gmt_module_init(void* p); |
||||||
|
} |
||||||
|
|
||||||
|
int callgmtmodule(void *api, const char *module, struct GMT_OPTION *opts, std::string& res); |
Loading…
Reference in new issue