wi_sqlite3_statement_t * wi_sqlite3_prepare_statement(wi_sqlite3_database_t *database, wi_string_t *query, ...) { wi_sqlite3_statement_t *statement; va_list ap; statement = wi_autorelease(wi_runtime_create_instance(_wi_sqlite3_statement_runtime_id, sizeof(wi_sqlite3_statement_t))); statement->query = wi_retain(query); wi_recursive_lock_lock(database->lock); if( #ifdef HAVE_SQLITE3_PREPARE_V2 sqlite3_prepare_v2 #else sqlite3_prepare #endif (database->database, wi_string_cstring(query), wi_string_length(query), &statement->statement, NULL) == SQLITE_OK) { va_start(ap, query); _wi_sqlite3_bind_statement(statement, ap); va_end(ap); } else { wi_error_set_sqlite3_error_with_description(database->database, wi_description(statement)); statement = NULL; } wi_recursive_lock_unlock(database->lock); return statement; }
void wd_user_unsubscribe_paths(wd_user_t *user) { wi_enumerator_t *enumerator; wi_string_t *path; wi_recursive_lock_lock(user->user_lock); enumerator = wi_array_data_enumerator(wi_set_all_data(user->subscribed_paths)); while((path = wi_enumerator_next_data(enumerator))) { wi_retain(path); while(wi_set_contains_data(user->subscribed_paths, path)) { if(wd_files_fsevents) wi_fsevents_remove_path(wd_files_fsevents, path); wi_mutable_set_remove_data(user->subscribed_paths, path); } wi_release(path); } wi_mutable_dictionary_remove_all_data(user->subscribed_virtualpaths); wi_recursive_lock_unlock(user->user_lock); }
void wd_chat_set_topic(wd_chat_t *chat, wd_topic_t *topic) { wi_recursive_lock_lock(chat->lock); wi_retain(topic); wi_release(chat->topic); chat->topic = topic; wi_recursive_lock_unlock(chat->lock); }
static void wd_users_update_idle(wi_timer_t *timer) { wi_enumerator_t *enumerator; wd_user_t *user; wi_time_interval_t interval; wi_dictionary_rdlock(wd_users); if(wi_dictionary_count(wd_users) > 0) { interval = wi_time_interval(); enumerator = wi_dictionary_data_enumerator(wd_users); while((user = wi_enumerator_next_data(enumerator))) { wi_recursive_lock_lock(user->user_lock); if(user->state == WD_USER_LOGGED_IN && !user->idle && user->idle_time + wd_settings.idletime < interval) { user->idle = true; wd_user_broadcast_status(user); } wi_recursive_lock_unlock(user->user_lock); } } wi_dictionary_unlock(wd_users); }
wi_array_t * wd_user_subscribed_virtual_paths_for_path(wd_user_t *user, wi_string_t *path) { wi_mutable_array_t *array; wi_string_t *virtualpath; array = wi_mutable_array(); wi_recursive_lock_lock(user->user_lock); if(wi_is_equal(wi_string_last_path_component(path), WI_STR(WD_FILES_META_PATH))) { path = wi_string_by_deleting_last_path_component(path); virtualpath = wi_dictionary_data_for_key(user->subscribed_virtualpaths, path); if(virtualpath) wi_mutable_array_add_data(array, virtualpath); if(!wi_is_equal(path, WI_STR("/"))) { path = wi_string_by_deleting_last_path_component(path); virtualpath = wi_dictionary_data_for_key(user->subscribed_virtualpaths, path); if(virtualpath) wi_mutable_array_add_data(array, virtualpath); } } else { virtualpath = wi_dictionary_data_for_key(user->subscribed_virtualpaths, path); if(virtualpath) wi_mutable_array_add_data(array, virtualpath); } wi_recursive_lock_unlock(user->user_lock); return array; }
wd_topic_t * wd_chat_topic(wd_chat_t *chat) { wd_topic_t *topic; wi_recursive_lock_lock(chat->lock); topic = wi_autorelease(wi_retain(chat->topic)); wi_recursive_lock_unlock(chat->lock); return topic; }
wi_string_t * wd_user_identifier(wd_user_t *user) { wi_string_t *identifier; wi_recursive_lock_lock(user->user_lock); identifier = wi_string_with_format(WI_STR("%@/%@/%@"), user->nick, user->login, user->ip); wi_recursive_lock_unlock(user->user_lock); return identifier; }
void wd_users_reply_users(wd_user_t *user, wi_p7_message_t *message) { wi_enumerator_t *enumerator; wi_p7_message_t *reply; wd_user_t *peer; wd_user_protocol_state_t state; wi_dictionary_rdlock(wd_users); enumerator = wi_dictionary_data_enumerator(wd_users); while((peer = wi_enumerator_next_data(enumerator))) { wi_recursive_lock_lock(peer->user_lock); switch(user->state) { default: case WD_USER_CONNECTED: state = WD_USER_PROTOCOL_CONNECTED; break; case WD_USER_GAVE_CLIENT_INFO: state = WD_USER_PROTOCOL_LOGGING_IN; break; case WD_USER_SAID_HELLO: state = WD_USER_PROTOCOL_LOGGING_IN; break; case WD_USER_GAVE_USER: state = WD_USER_PROTOCOL_LOGGING_IN; break; case WD_USER_LOGGED_IN: state = WD_USER_PROTOCOL_LOGGED_IN; break; case WD_USER_DISCONNECTED: state = WD_USER_PROTOCOL_DISCONNECTING; break; } reply = wi_p7_message_with_name(WI_STR("wired.user.user_list"), wd_p7_spec); wi_p7_message_set_uint32_for_name(reply, peer->id, WI_STR("wired.user.id")); wi_p7_message_set_bool_for_name(reply, peer->idle, WI_STR("wired.user.idle")); wi_p7_message_set_string_for_name(reply, peer->nick, WI_STR("wired.user.nick")); wi_p7_message_set_string_for_name(reply, peer->status, WI_STR("wired.user.status")); wi_p7_message_set_data_for_name(reply, peer->icon, WI_STR("wired.user.icon")); wi_p7_message_set_enum_for_name(reply, peer->color, WI_STR("wired.account.color")); wi_p7_message_set_date_for_name(reply, peer->idle_time, WI_STR("wired.user.idle_time")); if(peer->transfer) { state = WD_USER_PROTOCOL_TRANSFERRING; wi_p7_message_set_enum_for_name(reply, peer->transfer->type, WI_STR("wired.transfer.type")); wi_p7_message_set_string_for_name(reply, peer->transfer->path, WI_STR("wired.file.path")); wi_p7_message_set_uint64_for_name(reply, peer->transfer->datasize, WI_STR("wired.transfer.data_size")); wi_p7_message_set_uint64_for_name(reply, peer->transfer->rsrcsize, WI_STR("wired.transfer.rsrc_size")); wi_p7_message_set_uint64_for_name(reply, peer->transfer->transferred, WI_STR("wired.transfer.transferred")); wi_p7_message_set_uint32_for_name(reply, peer->transfer->speed, WI_STR("wired.transfer.speed")); wi_p7_message_set_uint32_for_name(reply, peer->transfer->queue, WI_STR("wired.transfer.queue_position")); } wi_p7_message_set_enum_for_name(reply, state, WI_STR("wired.user.state")); wi_recursive_lock_unlock(peer->user_lock); wd_user_reply_message(user, reply, message); } wi_dictionary_unlock(wd_users); reply = wi_p7_message_with_name(WI_STR("wired.user.user_list.done"), wd_p7_spec); wd_user_reply_message(user, reply, message); }
void wi_test_recursive_lock_locking(void) { #ifdef WI_PTHREADS wi_recursive_lock_t *lock; wi_boolean_t result; lock = wi_autorelease(wi_recursive_lock_init(wi_recursive_lock_alloc())); wi_recursive_lock_lock(lock); wi_recursive_lock_lock(lock); wi_recursive_lock_unlock(lock); wi_recursive_lock_unlock(lock); result = wi_recursive_lock_try_lock(lock); WI_TEST_ASSERT_TRUE(result, ""); result = wi_recursive_lock_try_lock(lock); WI_TEST_ASSERT_TRUE(result, ""); wi_recursive_lock_unlock(lock); wi_recursive_lock_unlock(lock); #endif }
void wd_user_broadcast_icon(wd_user_t *user) { wi_enumerator_t *enumerator; wi_p7_message_t *message; wd_chat_t *chat; enumerator = wi_array_data_enumerator(wd_chats_chats_with_user(user)); wi_recursive_lock_lock(user->user_lock); while((chat = wi_enumerator_next_data(enumerator))) { message = wi_p7_message_with_name(WI_STR("wired.chat.user_icon"), wd_p7_spec); wi_p7_message_set_uint32_for_name(message, user->id, WI_STR("wired.user.id")); wi_p7_message_set_uint32_for_name(message, wd_chat_id(chat), WI_STR("wired.chat.id")); wi_p7_message_set_data_for_name(message, user->icon, WI_STR("wired.user.icon")); wd_chat_broadcast_message(chat, message); } wi_recursive_lock_unlock(user->user_lock); }
void wd_user_unsubscribe_path(wd_user_t *user, wi_string_t *realpath) { wi_string_t *metapath; wi_recursive_lock_lock(user->user_lock); wi_mutable_set_remove_data(user->subscribed_paths, realpath); if(wd_files_fsevents) wi_fsevents_remove_path(wd_files_fsevents, realpath); metapath = wi_string_by_appending_path_component(realpath, WI_STR(WD_FILES_META_PATH)); wi_mutable_set_add_data(user->subscribed_paths, metapath); if(wd_files_fsevents) wi_fsevents_add_path(wd_files_fsevents, metapath); wi_mutable_dictionary_remove_data_for_key(user->subscribed_virtualpaths, realpath); wi_recursive_lock_unlock(user->user_lock); }
void wd_user_reply_user_info(wd_user_t *peer, wd_user_t *user, wi_p7_message_t *message) { wi_p7_message_t *reply; wi_cipher_t *cipher; wi_recursive_lock_lock(peer->user_lock); reply = wi_p7_message_with_name(WI_STR("wired.user.info"), wd_p7_spec); wi_p7_message_set_uint32_for_name(reply, peer->id, WI_STR("wired.user.id")); wi_p7_message_set_bool_for_name(reply, peer->idle, WI_STR("wired.user.idle")); wi_p7_message_set_string_for_name(reply, peer->login, WI_STR("wired.user.login")); wi_p7_message_set_string_for_name(reply, peer->nick, WI_STR("wired.user.nick")); wi_p7_message_set_string_for_name(reply, peer->status, WI_STR("wired.user.status")); wi_p7_message_set_data_for_name(reply, peer->icon, WI_STR("wired.user.icon")); wi_p7_message_set_enum_for_name(reply, peer->color, WI_STR("wired.account.color")); wi_p7_message_set_string_for_name(reply, peer->ip, WI_STR("wired.user.ip")); wi_p7_message_set_string_for_name(reply, peer->host, WI_STR("wired.user.host")); wi_p7_message_set_date_for_name(reply, peer->login_time, WI_STR("wired.user.login_time")); wi_p7_message_set_date_for_name(reply, peer->idle_time, WI_STR("wired.user.idle_time")); cipher = wi_p7_socket_cipher(peer->p7_socket); if(cipher) { wi_p7_message_set_string_for_name(reply, wi_cipher_name(cipher), WI_STR("wired.user.cipher.name")); wi_p7_message_set_uint32_for_name(reply, wi_cipher_bits(cipher), WI_STR("wired.user.cipher.bits")); } wi_p7_message_set_string_for_name(reply, peer->client_info->application_name, WI_STR("wired.info.application.name")); wi_p7_message_set_string_for_name(reply, peer->client_info->application_version, WI_STR("wired.info.application.version")); if(wi_string_length(peer->client_info->application_build) > 0) wi_p7_message_set_string_for_name(reply, peer->client_info->application_build, WI_STR("wired.info.application.build")); wi_p7_message_set_string_for_name(reply, peer->client_info->os_name, WI_STR("wired.info.os.name")); wi_p7_message_set_string_for_name(reply, peer->client_info->os_version, WI_STR("wired.info.os.version")); wi_p7_message_set_string_for_name(reply, peer->client_info->arch, WI_STR("wired.info.arch")); wi_recursive_lock_unlock(peer->user_lock); wd_user_reply_message(user, reply, message); }
void wd_user_broadcast_status(wd_user_t *user) { wi_enumerator_t *enumerator; wi_p7_message_t *message; wd_chat_t *chat; enumerator = wi_array_data_enumerator(wd_chats_chats_with_user(user)); wi_recursive_lock_lock(user->user_lock); while((chat = wi_enumerator_next_data(enumerator))) { message = wi_p7_message_with_name(WI_STR("wired.chat.user_status"), wd_p7_spec); wi_p7_message_set_uint32_for_name(message, wd_chat_id(chat), WI_STR("wired.chat.id")); wi_p7_message_set_uint32_for_name(message, user->id, WI_STR("wired.user.id")); wi_p7_message_set_bool_for_name(message, user->idle, WI_STR("wired.user.idle")); wi_p7_message_set_string_for_name(message, user->nick, WI_STR("wired.user.nick")); wi_p7_message_set_string_for_name(message, user->status, WI_STR("wired.user.status")); wi_p7_message_set_enum_for_name(message, user->color, WI_STR("wired.account.color")); wi_p7_message_set_date_for_name(message, user->idle_time, WI_STR("wired.user.idle_time")); wd_chat_broadcast_message(chat, message); } wi_recursive_lock_unlock(user->user_lock); }
void wi_sqlite3_rollback_transaction(wi_sqlite3_database_t *database) { if(!wi_sqlite3_execute_statement(database, WI_STR("ROLLBACK TRANSACTION"), NULL)) WI_ASSERT(0, "Could not execute database statement: %m"); wi_recursive_lock_unlock(database->lock); }
static void _wi_log_vlog(wi_log_level_t level, wi_string_t *fmt, va_list ap) { wi_string_t *string; FILE *fp = NULL; const char *cstring, *name, *path, *prefix; char date[_WI_LOG_DATE_SIZE]; int priority; if(_wi_log_in_callback) return; string = wi_string_init_with_format_and_arguments(wi_string_alloc(), fmt, ap); cstring = wi_string_cstring(string); name = wi_string_cstring(wi_process_name(wi_process())); _wi_log_date(date); switch(level) { default: case WI_LOG_INFO: priority = LOG_INFO; prefix = "Info"; break; case WI_LOG_WARN: priority = LOG_WARNING; prefix = "Warning"; break; case WI_LOG_ERR: priority = LOG_ERR; prefix = "Error"; break; case WI_LOG_DEBUG: priority = LOG_DEBUG; prefix = "Debug"; break; } if(wi_log_stdout || wi_log_stderr) { fp = wi_log_stdout ? stdout : stderr; fprintf(fp, "%s %s[%u]: %s: %s\n", date, name, (uint32_t) getpid(), prefix, cstring); } else if(wi_log_startup && level < WI_LOG_INFO) { fp = stderr; fprintf(fp, "%s: %s\n", name, cstring); } else if(wi_log_tool) { fp = (level < WI_LOG_INFO) ? stderr : stdout; fprintf(fp, "%s: %s\n", name, cstring); } else if(wi_log_plain) { fp = (level < WI_LOG_INFO) ? stderr : stdout; fprintf(fp, "%s\n", cstring); } if(fp) fflush(fp); if(wi_log_syslog) syslog(priority, "%s", cstring); if(wi_log_file && wi_log_path) { wi_recursive_lock_lock(_wi_log_lock); path = wi_string_cstring(wi_log_path); fp = fopen(path, "a"); if(fp) { fprintf(fp, "%s %s[%u]: %s: %s\n", date, name, (uint32_t) getpid(), prefix, cstring); fclose(fp); if(_wi_log_lines > 0 && wi_log_limit > 0) { if(_wi_log_lines % (int) ((float) wi_log_limit / 10.0f) == 0) { _wi_log_truncate(path); _wi_log_lines = wi_log_limit; } } _wi_log_lines++; } else { fprintf(stderr, "%s: %s: %s\n", name, path, strerror(errno)); } wi_recursive_lock_unlock(_wi_log_lock); } if(wi_log_callback) { _wi_log_in_callback = true; (*wi_log_callback)(level, string); _wi_log_in_callback = false; } if((wi_log_startup || wi_log_tool) && level == WI_LOG_ERR) exit(1); wi_release(string); }
void wd_user_unlock_socket(wd_user_t *user) { wi_recursive_lock_unlock(user->socket_lock); }
wi_dictionary_t * wi_sqlite3_fetch_statement_results(wi_sqlite3_database_t *database, wi_sqlite3_statement_t *statement) { wi_mutable_dictionary_t *results; wi_runtime_instance_t *instance; int i, count, length, result; wi_recursive_lock_lock(database->lock); result = sqlite3_step(statement->statement); switch(result) { case SQLITE_DONE: results = wi_dictionary(); sqlite3_finalize(statement->statement); statement->statement = NULL; break; case SQLITE_ROW: results = wi_mutable_dictionary(); count = sqlite3_column_count(statement->statement); for(i = 0; i < count; i++) { switch(sqlite3_column_type(statement->statement, i)) { case SQLITE_INTEGER: instance = wi_number_with_int64(sqlite3_column_int64(statement->statement, i)); break; case SQLITE_FLOAT: instance = wi_number_with_double(sqlite3_column_double(statement->statement, i)); break; case SQLITE_TEXT: instance = wi_string_with_cstring((const char *) sqlite3_column_text(statement->statement, i)); break; case SQLITE_BLOB: length = sqlite3_column_bytes(statement->statement, i); instance = wi_data_with_bytes(sqlite3_column_blob(statement->statement, i), length); break; case SQLITE_NULL: instance = wi_null(); break; default: instance = NULL; break; } if(instance) wi_mutable_dictionary_set_data_for_key(results, instance, wi_string_with_cstring(sqlite3_column_name(statement->statement, i))); } wi_runtime_make_immutable(results); break; default: wi_error_set_sqlite3_error_with_description(database->database, wi_description(statement)); sqlite3_finalize(statement->statement); statement->statement = NULL; results = NULL; break; } wi_recursive_lock_unlock(database->lock); return results; }