Example #1
0
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);
	}
}
Example #2
0
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);
}
Example #3
0
static wi_boolean_t wd_transfers_wait_until_ready(wd_transfer_t *transfer, wd_user_t *user, wi_p7_message_t *message) {
	wi_p7_message_t			*reply;
	wi_uinteger_t			queue;
	wi_p7_uint32_t			transaction;
	
	while(true) {
		if(wi_condition_lock_lock_when_condition(transfer->queue_lock, 1, 1.0)) {
			queue = transfer->queue;
			
			wi_condition_lock_unlock_with_condition(transfer->queue_lock, 0);
		
			if(queue > 0) {
				reply = wi_p7_message_with_name(WI_STR("wired.transfer.queue"), wd_p7_spec);
				wi_p7_message_set_string_for_name(reply, transfer->path, WI_STR("wired.file.path"));
				wi_p7_message_set_uint32_for_name(reply, queue, WI_STR("wired.transfer.queue_position"));

				if(wi_p7_message_get_uint32_for_name(message, &transaction, WI_STR("wired.transaction")))
					wi_p7_message_set_uint32_for_name(reply, transaction, WI_STR("wired.transaction"));
				
				if(!wd_user_write_message(user, 30.0, reply)) {
					wi_log_error(WI_STR("Could not write message \"%@\" to %@: %m"),
						wi_p7_message_name(reply), wd_user_identifier(user));
					
					return false;
				}
			} 
			
			if(queue == 0 || wd_user_state(user) != WD_USER_LOGGED_IN)
				return true;
		}
	}
}
Example #4
0
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 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);
}
Example #6
0
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;
}
Example #7
0
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);
	}
}
Example #8
0
static void _wi_timer_thread(wi_runtime_instance_t *argument) {
	wi_pool_t			*pool;
	wi_timer_t			*timer, *fire_timer;
	wi_time_interval_t	interval, diff;
	wi_boolean_t		locked;
	
	pool = wi_pool_init(wi_pool_alloc());
	
	while(true) {
		fire_timer	= NULL;
		locked		= true;
		interval	= wi_time_interval();
		timer		= _wi_timer_first_timer();

		if(!timer) {
			locked = wi_condition_lock_lock_when_condition(_wi_timer_lock, 1, 0.0);

			timer = _wi_timer_first_timer();
			interval = wi_time_interval();

			if(timer && timer->fire - interval <= _WI_TIMER_MINIMUM_INTERVAL)
				fire_timer = timer;
		} else {
			diff = timer->fire - interval;

			if(diff <= _WI_TIMER_MINIMUM_INTERVAL) {
				fire_timer = timer;

				locked = false;
			} else {
				locked = wi_condition_lock_lock_when_condition(_wi_timer_lock, 1, diff);
				
				if(!locked)
					fire_timer = _wi_timer_first_timer();
			} 
		}

		if(locked)
			wi_condition_lock_unlock_with_condition(_wi_timer_lock, 0);
		
		if(fire_timer) {
			_wi_timer_invalidate(fire_timer);
				
			wi_timer_fire(fire_timer);

			if(timer->repeats)
				_wi_timer_schedule(fire_timer);
		}
		
		wi_pool_drain(pool);
	}

	wi_release(pool);
}
Example #9
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);
}
Example #10
0
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);
	}
}
Example #11
0
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);
}
Example #12
0
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);
}
Example #13
0
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);
	}
}
Example #14
0
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);
}