static foreign_t in_pce_thread_sync2(term_t goal, term_t vars) { prolog_goal *g = malloc(sizeof(*g)); MSG msg; int rc = FALSE; if ( !g ) return PL_resource_error("memory"); if ( !init_prolog_goal(g, goal, TRUE) ) { free(g); return FALSE; } g->client = GetCurrentThreadId(); PostMessage(context.window, WM_CALL, (WPARAM)0, (LPARAM)g); while( GetMessage(&msg, NULL, 0, 0) ) { TranslateMessage(&msg); DispatchMessage(&msg); if ( PL_handle_signals() < 0 ) return FALSE; switch(g->state) { case G_TRUE: { term_t v = PL_new_term_ref(); rc = PL_recorded(g->result, v) && PL_unify(vars, v); PL_erase(g->result); goto out; } case G_FALSE: goto out; case G_ERROR: { term_t ex = PL_new_term_ref(); if ( PL_recorded(g->result, ex) ) rc = PL_raise_exception(ex); PL_erase(g->result); goto out; } default: continue; } } out: free(g); return rc; }
static void free_cgi_context(cgi_context *ctx) { if ( ctx->stream->upstream ) Sset_filter(ctx->stream, NULL); else PL_release_stream(ctx->stream); if ( ctx->data ) free(ctx->data); if ( ctx->hook ) PL_erase(ctx->hook); if ( ctx->request ) PL_erase(ctx->request); if ( ctx->header ) PL_erase(ctx->header); if ( ctx->connection ) PL_unregister_atom(ctx->connection); ctx->magic = 0; PL_free(ctx); }
static int set_term(record_t *r, term_t t) { if ( *r ) PL_erase(*r); *r = PL_record(t); return TRUE; }
static void call_prolog_goal(prolog_goal *g) { fid_t fid; static predicate_t pred = NULL; int rc; if ( !pred ) pred = PL_predicate("call", 1, "user"); if ( (fid = PL_open_foreign_frame()) ) { term_t t = PL_new_term_ref(); term_t vars; rc = PL_recorded(g->goal, t); PL_erase(g->goal); g->goal = 0; g->state = G_RUNNING; if ( rc ) { qid_t qid; int flags = PL_Q_NORMAL; if ( g->acknowledge ) { flags |= PL_Q_CATCH_EXCEPTION; vars = PL_new_term_ref(); if ( !PL_get_arg(2, t, vars) || /* Goal-Vars */ !PL_get_arg(1, t, t) ) { PL_warning("ERROR: in_pce_thread: bad goal-vars term"); } } else { vars = 0; } if ( (qid = PL_open_query(g->module, flags, pred, t)) ) { rc = PL_next_solution(qid); if ( rc ) { g->state = G_TRUE; if ( vars ) g->result = PL_record(vars); } else { term_t ex; if ( g->acknowledge && (ex=PL_exception(qid)) ) { g->result = PL_record(ex); g->state = G_ERROR; } else { g->state = G_FALSE; } } PL_cut_query(qid); } else PL_warning("ERROR: pce: out of global stack"); } PL_discard_foreign_frame(fid); } else PL_warning("ERROR: pce: out of global stack"); }
static void freeEvent(Event ev) { unlinkEvent(ev); if ( ev->goal ) PL_erase(ev->goal); ev->magic = 0; free(ev); }
static foreign_t in_pce_thread_sync2(term_t goal, term_t vars) { prolog_goal *g; int rc; if ( !setup() ) return FALSE; if ( !(g = malloc(sizeof(*g))) ) return PL_resource_error("memory"); if ( !init_prolog_goal(g, goal, TRUE) ) return FALSE; pthread_cond_init(&g->cv, NULL); pthread_mutex_init(&g->mutex, NULL); rc = write(context.pipe[1], &g, sizeof(g)); if ( rc == sizeof(g) ) { rc = FALSE; pthread_mutex_lock(&g->mutex); for(;;) { struct timespec timeout; #ifdef HAVE_CLOCK_GETTIME struct timespec now; clock_gettime(CLOCK_REALTIME, &now); timeout.tv_sec = now.tv_sec; timeout.tv_nsec = (now.tv_nsec+250000000); #else struct timeval now; gettimeofday(&now, NULL); timeout.tv_sec = now.tv_sec; timeout.tv_nsec = (now.tv_usec+250000) * 1000; #endif if ( timeout.tv_nsec >= 1000000000 ) /* some platforms demand this */ { timeout.tv_nsec -= 1000000000; timeout.tv_sec += 1; } pthread_cond_timedwait(&g->cv, &g->mutex, &timeout); if ( PL_handle_signals() < 0 ) goto out; switch(g->state) { case G_TRUE: { term_t v = PL_new_term_ref(); rc = PL_recorded(g->result, v) && PL_unify(vars, v); PL_erase(g->result); goto out; } case G_FALSE: goto out; case G_ERROR: { term_t ex = PL_new_term_ref(); if ( PL_recorded(g->result, ex) ) rc = PL_raise_exception(ex); PL_erase(g->result); goto out; } default: continue; } } out: pthread_mutex_unlock(&g->mutex); } pthread_mutex_destroy(&g->mutex); pthread_cond_destroy(&g->cv); free(g); return rc; }