int CMM_free(CMM_handle *cmm_handle, void *data) { if (cmm_handle == NULL) return 3; if (data == NULL) return 2; const size_t index = cmm_handle->hash_func(cmm_handle, data); Node *scanner = cmm_handle->hash_table[index], *prev = NULL; while (scanner != NULL && scanner->data != data) { prev = scanner; scanner = scanner->next; } if (scanner == NULL) return 1; if (prev == NULL) cmm_handle->hash_table[index] = scanner->next; else prev->next = scanner->next; free_node(cmm_handle, scanner); recycle_node(cmm_handle, scanner); return 0; }
void *db_worker(void *data) { int id = *((int *) data); /* Whoa... */ #ifndef STANDALONE int length; #endif /* NOT STANDALONE */ struct transaction_queue_node_t *node; struct db_context_t dbc; #ifdef STANDALONE struct timeval rt0, rt1; double response_time; #endif /* STANDALONE */ /* Open a connection to the database. */ #ifdef ODBC printf("connect to ODBC server with parameters: DSN: |%s| user: |%s| pass: |%s|\n", sname, dbt2_user, dbt2_pass); db_init(sname, dbt2_user, dbt2_pass); #endif /* ODBC */ #ifdef LIBPQ db_init(DB_NAME, sname, postmaster_port); #endif /* LIBPQ */ #ifdef LIBMYSQL printf("connect to mysql server with parameters: db_name: |%s| host: |%s| user: |%s| pass: |%s| port: |%s| socket: |%s|\n", sname, dbt2_mysql_host, dbt2_user, dbt2_pass, dbt2_mysql_port, dbt2_mysql_socket); db_init(sname, dbt2_mysql_host , dbt2_user, dbt2_pass, dbt2_mysql_port, dbt2_mysql_socket); #endif /* LIBMYSQL */ if (!exiting && connect_to_db(&dbc) != OK) { LOG_ERROR_MESSAGE("connect_to_db() error, terminating program"); printf("cannot connect to database(see details in error.log file, exiting...\n"); exit(1); } while (!exiting) { /* * I know this loop will prevent the program from exiting * because of the dequeue... */ node = dequeue_transaction(); if (node == NULL) { LOG_ERROR_MESSAGE("dequeue was null"); continue; } #ifdef STANDALONE if (gettimeofday(&rt0, NULL) == -1) { perror("gettimeofday"); } #endif /* STANDALONE */ node->client_data.status = process_transaction(node->client_data.transaction, &dbc, &node->client_data.transaction_data); if (node->client_data.status == ERROR) { LOG_ERROR_MESSAGE("process_transaction() error on %s", transaction_name[ node->client_data.transaction]); /* * Assume this isn't a fatal error, send the results * back, and try processing the next transaction. */ } else { if (node->client_data.status == ERROR_FATAL) { LOG_ERROR_MESSAGE("process_transaction() fatal error on %s", transaction_name[ node->client_data.transaction]); LOG_ERROR_MESSAGE("stopping db_thread"); exiting=1; } } #ifdef STANDALONE if (gettimeofday(&rt1, NULL) == -1) { perror("gettimeofday"); } response_time = difftimeval(rt1, rt0); pthread_mutex_lock(&mutex_mix_log); fprintf(log_mix, "%d,%c,%f,%d\n", (int) time(NULL), transaction_short_name[node->client_data.transaction], response_time, (int) pthread_self()); fflush(log_mix); pthread_mutex_unlock(&mutex_mix_log); #endif /* STANDALONE */ #ifndef STANDALONE length = send_transaction_data(node->s, &node->client_data); if (length == ERROR) { LOG_ERROR_MESSAGE("send_transaction_data() error"); /* * Assume this isn't a fatal error and try processing * the next transaction. */ } #endif /* NOT STANDALONE */ pthread_mutex_lock(&mutex_transaction_counter[REQ_EXECUTING][ node->client_data.transaction]); --transaction_counter[REQ_EXECUTING][ node->client_data.transaction]; pthread_mutex_unlock(&mutex_transaction_counter[REQ_EXECUTING][ node->client_data.transaction]); recycle_node(node); /* Keep track of how many transactions this thread has done. */ ++worker_count[id]; /* Keep track of then the last transaction was execute. */ time(&last_txn[id]); } /* Disconnect from the database. */ disconnect_from_db(&dbc); sem_wait(&db_worker_count); return NULL; /* keep compiler quiet */ }