static long get_thread_serial(long tno) { long *num; if (thread_id == NULL) return 0; num = cp_hashtable_get(thread_id, &tno); if (num == NULL) { long *key; num = malloc(sizeof(long)); if (num == NULL) { cp_error(CP_MEMORY_ALLOCATION_FAILURE, "can\'t allocate thread mapping number"); return -1L; } key = malloc(sizeof(long)); if (key == NULL) { cp_error(CP_MEMORY_ALLOCATION_FAILURE, "can\'t allocate thread mapping key"); return -1L; } *num = ++thread_count; *key = tno; cp_hashtable_put(thread_id, key, num); } return *num; }
cp_pooled_thread *cp_pooled_thread_create(cp_thread_pool *owner) { int rc; cp_pooled_thread *pt = calloc(1, sizeof(cp_pooled_thread)); if (pt == NULL) { cp_error(CP_MEMORY_ALLOCATION_FAILURE, "can\'t allocate pooled thread"); errno = ENOMEM; return NULL; } pt->worker = calloc(1, sizeof(cp_thread)); if (pt->worker == NULL) { cp_error(CP_MEMORY_ALLOCATION_FAILURE, "can\'t allocate thread"); errno = ENOMEM; return NULL; } pt->owner = owner; pt->suspend_lock = (cp_mutex *) malloc(sizeof(cp_mutex)); if (pt->suspend_lock == NULL) goto THREAD_CREATE_CANCEL; if ((rc = cp_mutex_init(pt->suspend_lock, NULL))) { cp_error(rc, "starting up pooled thread"); goto THREAD_CREATE_CANCEL; } pt->suspend_cond = (cp_cond *) malloc(sizeof(cp_cond)); if ((rc = cp_cond_init(pt->suspend_cond, NULL))) { cp_error(rc, "starting up pooled thread"); cp_mutex_destroy(pt->suspend_lock); free(pt->suspend_lock); goto THREAD_CREATE_CANCEL; } pt->done = 0; pt->wait = 1; cp_thread_create(*pt->worker, NULL, cp_pooled_thread_run, pt); pt->id = cp_pooled_thread_get_id(pt); cp_thread_detach(*pt->worker); //~~ check return pt; THREAD_CREATE_CANCEL: free(pt->worker); free(pt); return NULL; }
int cp_symbol_build_func(struct cp_ctype *type, const char *fname, int fn_size) { int i = 1, arg_nr, id; int *argsym_id_arr; csymbol nfcs; csymbol_func *fcs; if (cts.top == 0 || fn_size < 0 || !fname) { cp_error("invalid function definition.\n"); } argsym_id_arr = NULL; memset(&nfcs, 0, sizeof(csymbol)); csym_type(&nfcs) = FFI_FUNC; strncpy(csym_name(&nfcs), fname, fn_size); fcs = csym_func(&nfcs); fcs->has_var_arg = type->has_var_arg; /* Type needed for handling variable args handle */ if (fcs->has_var_arg && !ctype_lookup_type("void *")) cp_symbol_build_pointer(ctype_lookup_type("void")); /* Fetch start address of function */ fcs->addr = (void *)find_kernel_symbol(csym_name(&nfcs)); if (!fcs->addr) cp_error("wrong function address for %s\n", csym_name(&nfcs)); /* bottom of the stack is return type */ fcs->ret_id = ct_stack_ct(0)->ffi_cs_id; /* the rest is argument type */ if (cts.top == 1) { /* function takes no argument */ arg_nr = 0; } else { arg_nr = cts.top - 1; argsym_id_arr = malloc(arg_nr * sizeof(int)); if (!argsym_id_arr) cp_error("failed to allocate memory for function args.\n"); for (i = 0; i < arg_nr; i++) { argsym_id_arr[i] = ct_stack_ct(i+1)->ffi_cs_id; } } fcs->arg_nr = arg_nr; fcs->arg_ids = argsym_id_arr; id = cp_ctype_reg_csymbol(&nfcs); /* clear stack since we have consumed all the ctypes */ ctype_stack_reset(); return id; }
char *strndup(char *src, int maxlen) { int len; char *p; char *dst = NULL; if (maxlen < 0) { cp_error(CP_INVALID_VALUE, "negative string length requested"); errno = EINVAL; return NULL; } if (src != NULL) { /* null termination not guaranteed - can't use strlen */ for (p = src; *p && p - src < maxlen; p++); len = p - src; if (len > maxlen) len = maxlen; dst = (char *) malloc((len + 1) * sizeof(char)); if (dst == NULL) { errno = ENOMEM; return NULL; } memcpy(dst, src, len); dst[len] = '\0'; } return dst; }
int cp_pooled_thread_run_task(cp_pooled_thread *pt, cp_thread_action action, void *prm) { #ifdef __TRACE__ DEBUGMSG("cp_pooled_thread_run_task: action %lx, prm %lx\n", (long) action, (long) prm); #endif pt->action = action; pt->action_prm = prm; if (action == NULL) { cp_error(CP_INVALID_FUNCTION_POINTER, "missing thread function"); return CP_INVALID_FUNCTION_POINTER; } /* signal thread to run */ cp_mutex_lock(pt->suspend_lock); pt->wait = 0; cp_cond_signal(pt->suspend_cond); cp_mutex_unlock(pt->suspend_lock); return 0; }
int main(int argc, char *argv[]) { int rc = 0; struct sigaction act; cp_httpsocket *sock; cp_http_service *hitcount_svc = cp_http_service_create("hitcount", "/test", hitcount_service); process_cmdline(argc, argv); act.sa_handler = cpsvc_signal_handler; sigemptyset(&act.sa_mask); act.sa_flags = 0; cp_log_init("testhttpsrv.log", 0); cp_http_init(); /* override default http signal handler for stopping */ sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); cp_info("%s: starting", argv[0]); if ((rc = init_file_service(mimetypes_filename, document_root))) { cp_error(rc, "%s: can\'t start", argv[0]); goto DONE; } #ifdef CP_USE_SSL if (use_ssl) { sock = cp_httpsocket_create_ssl(port, (cp_http_service_callback) file_service, certificate_file, key_file, verify); } else #endif sock = cp_httpsocket_create(port, file_service); cp_httpsocket_register_service(sock, hitcount_svc); if (sock) { cp_info("%s: cp_httpsocket server starting on port %d", argv[0], port); cp_httpsocket_listen(sock); cp_info("%s: cp_httpsocket server on port %d: stopping", argv[0], port); cp_httpsocket_delete(sock); } DONE: stop_file_service(); cp_http_shutdown(); cp_info("done"); cp_log_close(); return rc; }
size_t ctype_size(const struct cp_ctype *ct) { if (ct->pointers - ct->is_array) { return sizeof(void*) * (ct->is_array ? ct->array_size : 1); } else if (!ct->is_defined || ct->type == VOID_TYPE) { cp_error("can't calculate size of an undefined type"); return 0; } else if (ct->variable_size_known) { assert(ct->is_variable_struct && !ct->is_array); return ct->base_size + ct->variable_increment; } else if (ct->is_variable_array || ct->is_variable_struct) { cp_error("internal error: calc size of variable type with " "unknown size"); return 0; } else { return ct->base_size * (ct->is_array ? ct->array_size : 1); } }
void cp_db_connection_set_fetch_size(cp_db_connection *connection, int fetch_size) { if (connection->data_source->act->fetch_next == NULL) { cp_error(CP_METHOD_NOT_IMPLEMENTED, "%s: can\'t set fetch size - method fetch_next not implemented", connection->data_source->act->dbms_lit); return; } connection->fetch_size = fetch_size; }
int ctype_reg_table_grow() { cp_ctype_entry *new_arr; new_arr = realloc(cte_arr, sizeof(cp_ctype_entry)*cte_arr_size*2); if (!new_arr) cp_error("failed to allocate memory for ctype array\n"); cte_arr_size = cte_arr_size * 2; return 0; }
int load_mime_types(char *filename) { FILE *fp; char mimebuf[LINELEN]; int rc = 0; char *name; char *ext; char *curr; mimemap = cp_hashtable_create_by_option(COLLECTION_MODE_NOSYNC | COLLECTION_MODE_COPY | COLLECTION_MODE_DEEP, 500, cp_hash_string, cp_hash_compare_string, (cp_copy_fn) strdup, (cp_destructor_fn) free, (cp_copy_fn) strdup, (cp_destructor_fn) free); fp = fopen(filename, "r"); if (fp == NULL) { cp_error(CP_INVALID_VALUE, "can\'t open %s", filename); cp_hashtable_destroy(mimemap); return -1; } while (fgets(mimebuf, LINELEN, fp)) { if (mimebuf[0] == '#') continue; name = curr = mimebuf; while (*curr && !isspace(*curr)) curr++; if (*curr == '\0') continue; /* no extension for this type */ *curr++ = '\0'; while (1) { while (*curr && isspace(*curr)) curr++; ext = curr; while (*curr && !isspace(*curr)) curr++; if (strlen(ext)) { *curr++ = '\0'; cp_hashtable_put(mimemap, ext, name); } else break; } } fclose(fp); return rc; }
void cp_db_connection_set_read_result_set_at_once(cp_db_connection *connection, int mode) { if (mode == 0 && connection->data_source->act->fetch_next == NULL) { cp_error(CP_METHOD_NOT_IMPLEMENTED, "%s: can\'t unset read at once mode - method fetch_next not " "implemented", connection->data_source->act->dbms_lit); return; } connection->read_result_set_at_once = mode; }
cp_string *cp_db_connection_unescape_binary(cp_db_connection *connection, char *src) { if (connection->data_source->act->unescape_binary) return (*connection->data_source->act->unescape_binary)(connection, src); cp_error(CP_METHOD_NOT_IMPLEMENTED, "%s driver does not implement unescape_binary", connection->data_source->act->dbms_lit); return cp_string_create(src, strlen(src)); }
char *cp_db_connection_escape_string(cp_db_connection *connection, char *src, int len) { if (connection->data_source->act->escape_string) return (*connection->data_source->act->escape_string)(connection, src, len); cp_error(CP_METHOD_NOT_IMPLEMENTED, "%s driver does not implement escape_string", connection->data_source->act->dbms_lit); return strdup(src); }
int cp_symbol_build_struct(const char *stname) { int i, id, memb_size; cp_ctype_entry *cte; csymbol nst; struct_member *st_membs; csymbol_struct *stcs; if (cts.top <= 0 || !stname) { cp_error("invalid struct definition.\n"); } memb_size = cts.top; st_membs = malloc(memb_size*sizeof(struct_member)); if (!st_membs) cp_error("failed to allocate memory for struct members.\n"); memset(st_membs, 0, memb_size*sizeof(struct_member)); nst.type = FFI_STRUCT; strcpy(nst.name, stname); stcs = csym_struct(&nst); stcs->memb_nr = memb_size; stcs->members = st_membs; for (i = 0; i < memb_size; i++) { assert(i < cts.top); cte = ct_stack(i); if (cte->name) strcpy(st_membs[i].name, cte->name); st_membs[i].id = ct_stack_ct(i)->ffi_cs_id; } id = cp_ctype_reg_csymbol(&nst); ctype_stack_reset(); return id; }
/* return index in csymbol array */ int cp_ctype_reg_csymbol(csymbol *cs) { if (cs_nr >= cs_arr_size) { cs_arr_size *= 2; cs_arr = realloc(cs_arr, cs_arr_size*sizeof(csymbol)); if (!cs_arr) cp_error("failed to extend csymbol array!\n"); } cs_arr[cs_nr] = *cs; cs_nr++; return cs_nr-1; }
cp_db_statement * cp_db_connection_prepare_statement(cp_db_connection *connection, int prm_count, cp_field_type *prm_types, char *query) { if (connection->data_source->act->prepare_statement) return (*connection->data_source->act->prepare_statement)(connection, prm_count, prm_types, query); cp_error(CP_METHOD_NOT_IMPLEMENTED, "%s driver does not implement prepare_statement", connection->data_source->act->dbms_lit); return NULL; }
char *cp_db_connection_escape_binary(cp_db_connection *connection, char *src, int src_len, int *res_len) { char *res; if (connection->data_source->act->escape_binary) return (*connection->data_source->act->escape_binary)(connection, src, src_len, res_len); cp_error(CP_METHOD_NOT_IMPLEMENTED, "%s driver does not implement escape_binary", connection->data_source->act->dbms_lit); *res_len = src_len; res = malloc(src_len); memcpy(res, src, src_len); return res; }
char *strnchr(char *str, char ch, int len) { char *res = NULL; if (len < 0) { cp_error(CP_INVALID_VALUE, "negative string length requested"); errno = EINVAL; return NULL; } while (len-- > 0) { if (*str == ch) { res = str; break; } if (*str++ == '\0') break; } return res; }
cp_thread_pool *cp_thread_pool_create(int min_size, int max_size) { int rc; cp_thread_pool *pool = calloc(1, sizeof(cp_thread_pool)); if (pool == NULL) cp_fatal(CP_MEMORY_ALLOCATION_FAILURE, "can\'t allocate thread pool structure"); pool->min_size = min_size; pool->max_size = max_size; pool->running = 1; pool->free_pool = cp_list_create(); if (pool->free_pool == NULL) cp_fatal(CP_MEMORY_ALLOCATION_FAILURE, "can\'t allocate thread pool list"); pool->in_use = cp_hashlist_create(10, cp_hash_long, cp_hash_compare_long); if (pool->in_use == NULL) cp_fatal(CP_MEMORY_ALLOCATION_FAILURE, "can\'t allocate thread pool running list"); pool->pool_lock = (cp_mutex *) malloc(sizeof(cp_mutex)); if (pool->pool_lock == NULL) { cp_error(CP_MEMORY_ALLOCATION_FAILURE, "can\'t create mutex"); goto THREAD_POOL_CREATE_CANCEL; } if ((rc = cp_mutex_init(pool->pool_lock, NULL))) { cp_error(rc, "can\'t create mutex"); goto THREAD_POOL_CREATE_CANCEL; } pool->pool_cond = (cp_cond *) malloc(sizeof(cp_cond)); if (pool->pool_cond == NULL) { cp_error(rc, "can\'t create condition variable"); cp_mutex_destroy(pool->pool_lock); free(pool->pool_lock); goto THREAD_POOL_CREATE_CANCEL; } if ((rc = cp_cond_init(pool->pool_cond, NULL))) { cp_error(rc, "can\'t create condition variable"); free(pool->pool_cond); cp_mutex_destroy(pool->pool_lock); free(pool->pool_lock); goto THREAD_POOL_CREATE_CANCEL; } for ( ; pool->size < pool->min_size; pool->size++) { cp_pooled_thread *pt = cp_pooled_thread_create(pool); if (pt == NULL) cp_fatal(CP_THREAD_CREATION_FAILURE, "can\'t create thread pool (created %d threads, minimum pool size is %d", pool->size, pool->min_size); cp_list_append(pool->free_pool, pt); } return pool; THREAD_POOL_CREATE_CANCEL: cp_list_destroy_custom(pool->free_pool, (cp_destructor_fn) cp_pooled_thread_destroy); cp_hashlist_destroy_custom(pool->in_use, NULL, (cp_destructor_fn) cp_pooled_thread_destroy); free(pool); return NULL; }
/** execute a prepared statement */ int cp_db_connection_execute_statement(cp_db_connection *connection, cp_db_statement *statement, cp_vector *prm, cp_result_set **results) { if (connection->data_source->act->execute_statement) { int rc; int *lengths = NULL; void **sprm = NULL; char *cstr; if (statement->prm_count) { int i; // cp_field_type *type; cp_string *str; lengths = calloc(statement->prm_count, sizeof(int)); sprm = calloc(statement->prm_count, sizeof(void *)); for (i = 0; i < statement->prm_count; i++) { sprm[i] = cp_vector_element_at(prm, i); switch (statement->types[i]) { case CP_FIELD_TYPE_BOOLEAN: case CP_FIELD_TYPE_SHORT: lengths[i] = sizeof(short); break; case CP_FIELD_TYPE_INT: lengths[i] = sizeof(int); break; case CP_FIELD_TYPE_LONG: lengths[i] = sizeof(long); break; case CP_FIELD_TYPE_LONG_LONG: #ifdef CP_HAS_LONG_LONG lengths[i] = sizeof(long long); break; #else lengths[i] = sizeof(__int64); break; #endif /* CP_HAS_LONG_LONG */ case CP_FIELD_TYPE_FLOAT: lengths[i] = sizeof(float); break; case CP_FIELD_TYPE_DOUBLE: lengths[i] = sizeof(double); break; case CP_FIELD_TYPE_CHAR: case CP_FIELD_TYPE_VARCHAR: cstr = cp_vector_element_at(prm, i); lengths[i] = strlen(cstr); break; case CP_FIELD_TYPE_BLOB: str = cp_vector_element_at(prm, i); lengths[i] = str->len; sprm[i] = str->data; break; case CP_FIELD_TYPE_DATE: case CP_FIELD_TYPE_TIME: case CP_FIELD_TYPE_TIMESTAMP: default: ; } } } rc = (*connection->data_source->act->execute_statement)(connection, statement, results, lengths, sprm); if (statement->prm_count) { free(lengths); free(sprm); } return rc; } cp_error(CP_METHOD_NOT_IMPLEMENTED, "%s driver does not implement execute_statement", connection->data_source->act->dbms_lit); return -1; }