void wd_transfer_loop(wd_transfer_t *transfer) { if(transfer->timer) wd_transfer_remove_timer(transfer); wi_condition_lock_lock(transfer->state_lock); if(transfer->state == WD_TRANSFER_WAITING) { transfer->state = WD_TRANSFER_RUNNING; wi_condition_lock_unlock_with_condition(transfer->state_lock, transfer->state); if(transfer->type == WD_TRANSFER_DOWNLOAD) wd_transfer_download(transfer); else wd_transfer_upload(transfer); } else { wi_condition_lock_unlock(transfer->state_lock); } wi_lock_lock(wd_transfers_update_queue_lock); wi_array_wrlock(wd_transfers); wi_mutable_array_remove_data(wd_transfers, transfer); wi_array_unlock(wd_transfers); wd_transfers_update_queue(); wi_lock_unlock(wd_transfers_update_queue_lock); }
void wd_transfers_apply_settings(wi_set_t *changes) { wd_transfers_total_downloads = wi_config_integer_for_name(wd_config, WI_STR("total downloads")); wd_transfers_total_uploads = wi_config_integer_for_name(wd_config, WI_STR("total uploads")); wd_transfers_total_download_speed = wi_config_integer_for_name(wd_config, WI_STR("total download speed")); wd_transfers_total_upload_speed = wi_config_integer_for_name(wd_config, WI_STR("total upload speed")); wi_condition_lock_lock(wd_transfers_queue_lock); wi_condition_lock_unlock_with_condition(wd_transfers_queue_lock, 1); }
static wd_transfer_state_t wd_transfer_state(wd_transfer_t *transfer) { wd_transfer_state_t state; wi_condition_lock_lock(transfer->state_lock); state = transfer->state; wi_condition_lock_unlock(transfer->state_lock); return state; }
static void _wi_test_filesystem_events_callback(wi_filesystem_events_t *filesystem_events, wi_string_t *path) { wi_condition_lock_lock(_wi_test_filesystem_events_lock); wi_mutable_set_add_data(_wi_test_filesystem_events_paths, path); wi_condition_lock_unlock_with_condition(_wi_test_filesystem_events_lock, 1); wi_filesystem_events_remove_path(filesystem_events, path); }
wi_boolean_t wd_transfers_run_transfer(wd_transfer_t *transfer, wd_user_t *user, wi_p7_message_t *message) { wi_boolean_t result = false; wi_array_wrlock(wd_transfers); wi_mutable_array_add_data(wd_transfers, transfer); wi_array_unlock(wd_transfers); wi_condition_lock_lock(wd_transfers_queue_lock); wi_condition_lock_unlock_with_condition(wd_transfers_queue_lock, 1); if(wd_transfers_wait_until_ready(transfer, user, message)) { wi_condition_lock_lock(transfer->queue_lock); transfer->state = WD_TRANSFER_RUNNING; wi_condition_lock_unlock(transfer->queue_lock); if(transfer->type == WD_TRANSFER_DOWNLOAD) result = wd_transfers_run_download(transfer, user, message); else result = wd_transfers_run_upload(transfer, user, message); wi_condition_lock_lock(transfer->finished_lock); wi_condition_lock_unlock_with_condition(transfer->finished_lock, 1); } else { wi_log_error(WI_STR("Could not process %@ for %@: %m"), (transfer->type == WD_TRANSFER_DOWNLOAD) ? WI_STR("download") : WI_STR("upload"), wd_user_identifier(user)); } if(transfer->queue == 0) wd_transfers_add_or_remove_transfer(transfer, false); wi_array_wrlock(wd_transfers); wi_mutable_array_remove_data(wd_transfers, transfer); wi_array_unlock(wd_transfers); wi_condition_lock_lock(wd_transfers_queue_lock); wi_condition_lock_unlock_with_condition(wd_transfers_queue_lock, 1); return result; }
void wi_timer_invalidate(wi_timer_t *timer) { if(timer->scheduled) { if(!timer->incallback) wi_condition_lock_lock(_wi_timer_lock); _wi_timer_invalidate(timer); if(!timer->incallback) wi_condition_lock_unlock_with_condition(_wi_timer_lock, 1); } }
static void _wi_test_timer_function(wi_timer_t *timer) { wi_condition_lock_lock(_wi_test_timer_lock); if(++_wi_test_timer_hits == 5) { wi_timer_invalidate(timer); wi_condition_lock_unlock_with_condition(_wi_test_timer_lock, 1); } else { wi_timer_schedule(timer); wi_condition_lock_unlock_with_condition(_wi_test_timer_lock, 0); } }
static void wi_test_fsevents_thread(wi_runtime_instance_t *instance) { wi_pool_t *pool; pool = wi_pool_init(wi_pool_alloc()); if(!wi_fsevents_run_with_timeout(wi_test_fsevents_fsevents, 1.0)) wi_log_warn(WI_STR("wi_fsevents_run_with_timeout: %m")); wi_condition_lock_lock(wi_test_fsevents_lock); wi_condition_lock_unlock_with_condition(wi_test_fsevents_lock, 1); wi_release(pool); }
void wi_timer_schedule(wi_timer_t *timer) { if(!timer->scheduled) { pthread_once(&_wi_timer_once_control, _wi_timer_create_thread); if(!timer->incallback) wi_condition_lock_lock(_wi_timer_lock); _wi_timer_schedule(timer); if(!timer->incallback) wi_condition_lock_unlock_with_condition(_wi_timer_lock, 1); } }
void wi_timer_reschedule(wi_timer_t *timer, wi_time_interval_t interval) { timer->interval = WI_MAX(interval, _WI_TIMER_MINIMUM_INTERVAL); if(timer->scheduled) _wi_timer_invalidate(timer); if(!timer->incallback) wi_condition_lock_lock(_wi_timer_lock); _wi_timer_schedule(timer); if(!timer->incallback) wi_condition_lock_unlock_with_condition(_wi_timer_lock, 1); }
static void wd_transfer_set_state(wd_transfer_t *transfer, wd_transfer_state_t state) { wi_condition_lock_lock(transfer->state_lock); transfer->state = state; wi_condition_lock_unlock_with_condition(transfer->state_lock, transfer->state); }
static void wi_test_fsevents_callback(wi_string_t *path) { wi_condition_lock_lock(wi_test_fsevents_lock); wi_test_fsevents_path = wi_retain(path); wi_condition_lock_unlock(wi_test_fsevents_lock); }
void wd_transfers_remove_user(wd_user_t *user, wi_boolean_t removingallusers) { wi_enumerator_t *enumerator; wi_string_t *key; wd_user_t *each_user; wd_transfer_t *transfer; wi_uinteger_t i, count; wi_boolean_t update = false, present = false; key = wd_transfers_transfer_key_for_user(user); if(!key) return; if(!removingallusers) { wi_dictionary_rdlock(wd_users); enumerator = wi_dictionary_data_enumerator(wd_users); while((each_user = wi_enumerator_next_data(enumerator))) { if(wd_user_state(each_user) == WD_USER_LOGGED_IN && wi_is_equal(wd_transfers_transfer_key_for_user(each_user), key)) { present = true; break; } } wi_dictionary_unlock(wd_users); } if(!present) { wi_array_wrlock(wd_transfers); count = wi_array_count(wd_transfers); for(i = 0; i < count; i++) { transfer = WI_ARRAY(wd_transfers, i); if(wi_is_equal(key, transfer->key)) { wd_user_set_state(transfer->user, WD_USER_DISCONNECTED); if(transfer->state == WD_TRANSFER_RUNNING) { if(wi_condition_lock_lock_when_condition(transfer->finished_lock, 1, 1.0)) wi_condition_lock_unlock(transfer->finished_lock); } else { wi_mutable_array_remove_data_at_index(wd_transfers, i); i--; count--; update = true; } } } if(update) { wi_condition_lock_lock(wd_transfers_queue_lock); wi_condition_lock_unlock_with_condition(wd_transfers_queue_lock, 1); } wi_array_unlock(wd_transfers); } }
static void wd_transfers_queue_thread(wi_runtime_instance_t *argument) { wi_pool_t *pool; wi_enumerator_t *enumerator; wi_mutable_dictionary_t *key_queues; wi_mutable_array_t *key_queue, *keys; wi_string_t *key; wd_transfer_t *transfer; wd_account_t *account; wi_uinteger_t user_downloads, user_uploads, user_transfers; wi_uinteger_t new_position, position, queue, i, count, longest_queue; pool = wi_pool_init(wi_pool_alloc()); key_queues = wi_dictionary_init(wi_mutable_dictionary_alloc()); while(true) { wi_mutable_dictionary_remove_all_data(key_queues); wi_condition_lock_lock_when_condition(wd_transfers_queue_lock, 1, 0.0); wi_array_rdlock(wd_transfers); longest_queue = 0; enumerator = wi_array_data_enumerator(wd_transfers); while((transfer = wi_enumerator_next_data(enumerator))) { wi_condition_lock_lock(transfer->queue_lock); if(transfer->state == WD_TRANSFER_QUEUED && transfer->queue != 0) { key_queue = wi_dictionary_data_for_key(key_queues, transfer->key); if(!key_queue) { key_queue = wi_mutable_array(); wi_mutable_dictionary_set_data_for_key(key_queues, key_queue, transfer->key); } wi_mutable_array_add_data(key_queue, transfer); if(wi_array_count(key_queue) > longest_queue) longest_queue = wi_array_count(key_queue); } wi_condition_lock_unlock(transfer->queue_lock); } keys = wi_autorelease(wi_mutable_copy(wi_dictionary_keys_sorted_by_value(key_queues, wd_transfers_queue_compare))); position = 1; count = wi_array_count(keys); while(longest_queue > 0) { for(i = 0; i < count; i++) { key = WI_ARRAY(keys, i); key_queue = wi_dictionary_data_for_key(key_queues, key); if(wi_array_count(key_queue) > 0) { transfer = WI_ARRAY(key_queue, 0); account = wd_user_account(transfer->user); wi_lock_lock(wd_transfers_status_lock); if(transfer->type == WD_TRANSFER_DOWNLOAD) { wi_dictionary_rdlock(wd_transfers_user_downloads); user_downloads = wd_account_transfer_download_limit(account); user_transfers = (wi_integer_t) wi_dictionary_data_for_key(wd_transfers_user_downloads, transfer->key); queue = ((wd_transfers_total_downloads > 0 && wd_transfers_active_downloads >= wd_transfers_total_downloads) || (user_downloads > 0 && user_transfers >= user_downloads)); wi_dictionary_unlock(wd_transfers_user_downloads); } else { wi_dictionary_rdlock(wd_transfers_user_uploads); user_uploads = wd_account_transfer_upload_limit(account); user_transfers = (wi_integer_t) wi_dictionary_data_for_key(wd_transfers_user_uploads, transfer->key); queue = ((wd_transfers_total_uploads > 0 && wd_transfers_active_uploads >= wd_transfers_total_uploads) || (user_uploads > 0 && user_transfers >= user_uploads)); wi_dictionary_unlock(wd_transfers_user_uploads); } wi_lock_unlock(wd_transfers_status_lock); if(queue) new_position = position++; else new_position = 0; if(new_position != (wi_uinteger_t) transfer->queue) { if(new_position == 0) wd_transfers_add_or_remove_transfer(transfer, true); wi_condition_lock_lock(transfer->queue_lock); transfer->queue = new_position; wi_condition_lock_unlock_with_condition(transfer->queue_lock, 1); } wi_mutable_array_remove_data_at_index(key_queue, 0); } } longest_queue--; } wi_array_unlock(wd_transfers); wi_condition_lock_unlock_with_condition(wd_transfers_queue_lock, 0); wi_pool_drain(pool); } wi_release(key_queues); wi_release(pool); }