コード例 #1
0
ファイル: wi-timer.c プロジェクト: Patater/libwired
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);
}
コード例 #2
0
ファイル: transfers.c プロジェクト: ProfDrLuigi/zanka
void wd_transfers_remove_client(wd_client_t *client) {
	wi_list_node_t	*node, *next_node;
	wd_transfer_t	*transfer;
	wi_boolean_t	update = false;

	wi_list_wrlock(wd_transfers);
	for(node = wi_list_first_node(wd_transfers); node; node = next_node) {
		next_node	= wi_list_node_next_node(node);
		transfer	= wi_list_node_data(node);

		if(transfer->state <= WD_TRANSFER_RUNNING &&
		   transfer->client == client) {
			if(transfer->state == WD_TRANSFER_RUNNING) {
				wi_list_unlock(wd_transfers);
				wd_transfer_set_state(transfer, WD_TRANSFER_STOP);
				
				wi_condition_lock_lock_when_condition(transfer->state_lock, WD_TRANSFER_STOPPED, 5.0);
				wi_condition_lock_unlock(transfer->state_lock);
				wi_list_wrlock(wd_transfers);
			} else {
				wi_list_remove_node(wd_transfers, node);

				update = true;
			}
		}
	}
	wi_list_unlock(wd_transfers);
	
	if(update)
		wd_transfers_update_queue();
}
コード例 #3
0
ファイル: transfers.c プロジェクト: ProfDrLuigi/zanka
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;
		}
	}
}
コード例 #4
0
ファイル: transfers.c プロジェクト: ProfDrLuigi/zanka
void wd_transfers_remove_user(wd_user_t *user) {
	wd_transfer_t			*transfer;
	wi_boolean_t			update = false;
	wi_uinteger_t			i, count;
	wd_transfer_state_t		state;

	wi_lock_lock(wd_transfers_update_queue_lock);
	wi_array_wrlock(wd_transfers);
	
	count = wi_array_count(wd_transfers);
	
	for(i = 0; i < count; i++) {
		transfer = WI_ARRAY(wd_transfers, i);
		
		if(transfer->user == user) {
			state = wd_transfer_state(transfer);
			
			if(state == WD_TRANSFER_RUNNING) {
				wi_array_unlock(wd_transfers);
				
				wd_transfer_set_state(transfer, WD_TRANSFER_STOP);
				
				wi_condition_lock_lock_when_condition(transfer->state_lock, WD_TRANSFER_STOPPED, 1.0);
				wi_condition_lock_unlock(transfer->state_lock);
				
				wi_array_wrlock(wd_transfers);
			}
			else if(state == WD_TRANSFER_QUEUED || state == WD_TRANSFER_WAITING) {
				if(transfer->timer)
					wd_transfer_remove_timer(transfer);
				
				wi_mutable_array_remove_data_at_index(wd_transfers, i);

				count--;
				i--;
				update = true;
			}
		}
	}
	
	wi_array_unlock(wd_transfers);
	
	if(update)
		wd_transfers_update_queue();

	wi_lock_unlock(wd_transfers_update_queue_lock);
}
コード例 #5
0
ファイル: wi-fsevents-tests.c プロジェクト: ProfDrLuigi/zanka
void wi_test_fsevents(void) {
#ifdef WI_PTHREADS
	wi_string_t			*directory;
	
	wi_test_fsevents_fsevents = wi_fsevents_init(wi_fsevents_alloc());
	
	if(!wi_test_fsevents_fsevents) {
		if(wi_error_domain() != WI_ERROR_DOMAIN_LIBWIRED && wi_error_code() != WI_ERROR_FSEVENTS_NOTSUPP)
			WI_TEST_ASSERT_NOT_NULL(wi_test_fsevents_fsevents, "%m");
		
		return;
	}
	
	directory = wi_fs_temporary_path_with_template(WI_STR("/tmp/libwired-fsevents.XXXXXXXX"));
	
	wi_fs_create_directory(directory, 0700);
	
	wi_fsevents_add_path(wi_test_fsevents_fsevents, directory);
	wi_fsevents_set_callback(wi_test_fsevents_fsevents, wi_test_fsevents_callback);
	
	wi_test_fsevents_lock = wi_condition_lock_init_with_condition(wi_condition_lock_alloc(), 0);
	
	if(!wi_thread_create_thread(wi_test_fsevents_thread, NULL))
		WI_TEST_FAIL("%m");
	
	wi_thread_sleep(0.1);
	
	wi_string_write_to_file(WI_STR("foo"), wi_string_by_appending_path_component(directory, WI_STR("file")));
	
	wi_condition_lock_lock_when_condition(wi_test_fsevents_lock, 1, 0.0);
	
	if(!wi_test_fsevents_path)
		WI_TEST_FAIL("No fsevents callback received");
	else
		WI_TEST_ASSERT_EQUAL_INSTANCES(wi_test_fsevents_path, directory, "");
	
	wi_condition_lock_unlock(wi_test_fsevents_lock);

	wi_fs_delete_path(directory);
	
	wi_release(wi_test_fsevents_lock);
	wi_release(wi_test_fsevents_fsevents);
	wi_release(wi_test_fsevents_path);
#endif
}
コード例 #6
0
ファイル: wi-timer-tests.c プロジェクト: asvitkine/phxd
void wi_test_timer(void) {
#ifdef WI_PTHREADS
	wi_timer_t		*timer;
	
	_wi_test_timer_lock = wi_autorelease(wi_condition_lock_init_with_condition(wi_condition_lock_alloc(), 0));
	
	timer = wi_autorelease(wi_timer_init_with_function(wi_timer_alloc(), _wi_test_timer_function, 0.001, false));
	wi_timer_schedule(timer);
	
	if(wi_condition_lock_lock_when_condition(_wi_test_timer_lock, 1, 1.0)) {
		WI_TEST_ASSERT_EQUALS(_wi_test_timer_hits, 5U, "");
		wi_condition_lock_unlock(_wi_test_timer_lock);
	} else {
		WI_TEST_FAIL("Timed out waiting for timer, currently at %u %s",
			_wi_test_timer_hits, _wi_test_timer_hits == 1 ? "hit" : "hits");
	}
#endif
}
コード例 #7
0
void wi_test_filesystem_events(void) {
#if defined(WI_FILESYSTEM_EVENTS)
    wi_filesystem_events_t  *filesystem_events;
    wi_string_t             *path;
    wi_boolean_t            result;
    
    _wi_test_filesystem_events_lock = wi_autorelease(wi_condition_lock_init_with_condition(wi_condition_lock_alloc(), 0));
    _wi_test_filesystem_events_paths = wi_mutable_set();
    
    path = wi_filesystem_temporary_path_with_template(WI_STR("/tmp/libwired-test-filesystem.XXXXXXX"));
    
    WI_TEST_ASSERT_NOT_NULL(path, "");
    
    result = wi_filesystem_create_directory_at_path(path);
    
    WI_TEST_ASSERT_TRUE(result, "");
    
    filesystem_events = wi_filesystem_events();
    
    WI_TEST_ASSERT_NOT_NULL(filesystem_events, "");
    
    result = wi_filesystem_events_add_path_with_callback(filesystem_events, path, _wi_test_filesystem_events_callback);
    
    WI_TEST_ASSERT_TRUE(result, "");
    
    result = wi_string_write_utf8_string_to_path(WI_STR("hello world"), wi_string_by_appending_path_component(path, WI_STR("foobar")));
    
    WI_TEST_ASSERT_TRUE(result, "");
    
    if(!wi_condition_lock_lock_when_condition(_wi_test_filesystem_events_lock, 1, 1.0))
        WI_TEST_FAIL("timed out waiting for filesystem events thread");
    
    WI_TEST_ASSERT_EQUAL_INSTANCES(_wi_test_filesystem_events_paths, wi_set_with_data(path, NULL), "");
    
    wi_condition_lock_unlock(_wi_test_filesystem_events_lock);
#endif
}
コード例 #8
0
ファイル: transfers.c プロジェクト: ProfDrLuigi/zanka
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);
	}
}
コード例 #9
0
ファイル: transfers.c プロジェクト: ProfDrLuigi/zanka
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);
}