Esempio n. 1
0
DECLARE_TEST(objectmap, store) {
	objectmap_t* map;
	object_base_t first;
	object_base_t second;
	object_base_t third;

	map = objectmap_allocate(129);
	
	memset(&first, 0, sizeof(first));
	memset(&second, 0, sizeof(first));
	memset(&third, 0, sizeof(first));
	atomic_store32(&first.ref, 1);
	atomic_store32(&second.ref, 1);
	atomic_store32(&third.ref, 1);
	first.id = 1;
	second.id = 2;
	third.id = 3;

	EXPECT_EQ(objectmap_lookup(map, 0), 0);
	EXPECT_EQ(objectmap_lookup(map, 1), 0);

	first.id = objectmap_reserve(map);
	EXPECT_EQ(objectmap_lookup(map, first.id), 0);
	EXPECT_EQ(objectmap_raw_lookup(map, 0), 0);

	second.id = objectmap_reserve(map);
	EXPECT_EQ(objectmap_lookup(map, first.id), 0);
	EXPECT_EQ(objectmap_raw_lookup(map, 0), 0);
	EXPECT_EQ(objectmap_lookup(map, second.id), 0);
	EXPECT_EQ(objectmap_raw_lookup(map, 1), 0);

	objectmap_set(map, first.id, &first);
	EXPECT_EQ(objectmap_lookup(map, first.id), &first);
	EXPECT_EQ(objectmap_raw_lookup(map, 0), &first);
	EXPECT_EQ(objectmap_lookup(map, second.id), 0);
	EXPECT_EQ(objectmap_raw_lookup(map, 1), 0);

	objectmap_set(map, second.id, &second);
	EXPECT_EQ(objectmap_lookup(map, first.id), &first);
	EXPECT_EQ(objectmap_raw_lookup(map, 0), &first);
	EXPECT_EQ(objectmap_lookup(map, second.id), &second);
	EXPECT_EQ(objectmap_raw_lookup(map, 1), &second);

	objectmap_free(map, first.id);
	EXPECT_EQ(objectmap_lookup(map, first.id), 0);
	EXPECT_EQ(objectmap_raw_lookup(map, 0), 0);
	EXPECT_EQ(objectmap_lookup(map, second.id), &second);
	EXPECT_EQ(objectmap_raw_lookup(map, 1), &second);

	objectmap_free(map, first.id);
	EXPECT_EQ(objectmap_lookup(map, first.id), 0);
	EXPECT_EQ(objectmap_raw_lookup(map, 0), 0);
	EXPECT_EQ(objectmap_lookup(map, second.id), &second);
	EXPECT_EQ(objectmap_raw_lookup(map, 1), &second);

	objectmap_free(map, second.id);
	EXPECT_EQ(objectmap_lookup(map, first.id), 0);
	EXPECT_EQ(objectmap_raw_lookup(map, 0), 0);
	EXPECT_EQ(objectmap_lookup(map, second.id), 0);
	EXPECT_EQ(objectmap_raw_lookup(map, 1), 0);

	objectmap_deallocate(map);

	//Size should be clamped to three
	map = objectmap_allocate(1);

	EXPECT_EQ(objectmap_lookup(map, 0), 0);
	EXPECT_EQ(objectmap_lookup(map, 1), 0);

	first.id = objectmap_reserve(map);
	EXPECT_TYPENE(first.id, 0, object_t, PRIx64);
	EXPECT_EQ(objectmap_lookup(map, first.id), 0);
	EXPECT_EQ(objectmap_raw_lookup(map, 0), 0);

	second.id = objectmap_reserve(map);
	EXPECT_TYPENE(second.id, 0, object_t, PRIx64);
	EXPECT_EQ(objectmap_lookup(map, first.id), 0);
	EXPECT_EQ(objectmap_raw_lookup(map, 0), 0);
	EXPECT_EQ(objectmap_lookup(map, second.id), 0);
	EXPECT_EQ(objectmap_raw_lookup(map, 1), 0);

	third.id = objectmap_reserve(map);
	EXPECT_TYPENE(third.id, 0, object_t, PRIx64);
	EXPECT_EQ(objectmap_lookup(map, first.id), 0);
	EXPECT_EQ(objectmap_raw_lookup(map, 0), 0);
	EXPECT_EQ(objectmap_lookup(map, second.id), 0);
	EXPECT_EQ(objectmap_raw_lookup(map, 1), 0);
	EXPECT_EQ(objectmap_lookup(map, third.id), 0);
	EXPECT_EQ(objectmap_raw_lookup(map, 1), 0);

	objectmap_set(map, first.id, &first);
	objectmap_set(map, second.id, &second);
	objectmap_set(map, third.id, &third);

	log_enable_stdout(false);
	EXPECT_TYPEEQ(objectmap_reserve(map), 0, object_t, PRIx64);
	EXPECT_TYPEEQ(objectmap_reserve(map), 0, object_t, PRIx64);
	log_enable_stdout(true);

	objectmap_free(map, first.id);
	objectmap_free(map, second.id);
	//Leak one object
	//objectmap_free(map, third.id);
	EXPECT_EQ(objectmap_lookup_ref(map, first.id), nullptr);
	EXPECT_EQ(objectmap_raw_lookup(map, 0), 0);
	EXPECT_EQ(objectmap_lookup_ref(map, second.id), nullptr);
	EXPECT_EQ(objectmap_raw_lookup(map, 1), 0);
	EXPECT_NE(objectmap_lookup_ref(map, third.id), nullptr);
	EXPECT_NE(objectmap_raw_lookup(map, 2), 0);

	log_enable_stdout(false);
	objectmap_deallocate(map);
	log_enable_stdout(true);

	return 0;
}
Esempio n. 2
0
object_t library_load( const char* name )
{
	library_t* library;
	hash_t namehash;
	unsigned int i, size;
	uint64_t id;
#if FOUNDATION_PLATFORM_WINDOWS
	char* dllname;
	HANDLE dll;
#endif

	//Locate already loaded library
	library = 0;
	namehash = string_hash( name );
	for( i = 0, size = objectmap_size( _library_map ); i < size; ++i )
	{
		library = objectmap_raw_lookup( _library_map, i );
		if( library && ( library->namehash == namehash ) )
		{
			FOUNDATION_ASSERT( string_equal( library->name, name ) );
			atomic_incr32( &library->ref );
			return library->id;
		}
	}
	
	error_context_push( "loading library", name );

	//Try loading library
#if FOUNDATION_PLATFORM_WINDOWS

	dllname = string_format( "%s.dll", name );
	dll = LoadLibraryA( dllname );
	if( !dll )
	{
#if FOUNDATION_PLATFORM_ARCH_X86
		string_deallocate( dllname );
		dllname = string_format( "%s32.dll", name );
		dll = LoadLibraryA( dllname );
#elif FOUNDATION_PLATFORM_ARCH_X86_64
		string_deallocate( dllname );
		dllname = string_format( "%s64.dll", name );
		dll = LoadLibraryA( dllname );
#endif
	}
	string_deallocate( dllname );
	if( !dll )
	{
		log_warnf( 0, WARNING_SUSPICIOUS, "Unable to load DLL '%s': %s", name, system_error_message( 0 ) );
		error_context_pop();
		return 0;
	}

#elif FOUNDATION_PLATFORM_POSIX

#  if FOUNDATION_PLATFORM_APPLE
	char* libname = string_format( "lib%s.dylib", name );
#  else
	char* libname = string_format( "lib%s.so", name );
#  endif
	void* lib = dlopen( libname, RTLD_LAZY );
	string_deallocate( libname );
#if FOUNDATION_PLATFORM_ANDROID
	if( !lib )
	{
		libname = string_format( "%s/lib%s.so", environment_executable_directory(), name );
		lib = dlopen( libname, RTLD_LAZY );
		string_deallocate( libname );
	}
#endif
	if( !lib )
	{
		log_warnf( 0, WARNING_SUSPICIOUS, "Unable to load dynamic library '%s': %s", name, dlerror() );
		error_context_pop();
		return 0;
	}

#else
	
	log_errorf( 0, ERROR_NOT_IMPLEMENTED, "Dynamic library loading not implemented for this platform: %s", name );
	error_context_pop();
	return 0;

#endif

	id = objectmap_reserve( _library_map );
	if( !id )
	{
#if FOUNDATION_PLATFORM_WINDOWS
		FreeLibrary( dll );
#elif FOUNDATION_PLATFORM_POSIX
		dlclose( lib );
#endif
		log_errorf( 0, ERROR_OUT_OF_MEMORY, "Unable to allocate new library '%s', map full", name );	
		error_context_pop();
		return 0;
	}
	library = memory_allocate_zero( sizeof( library_t ), 0, MEMORY_PERSISTENT );
	library->ref = 1;
	library->id = id;
	library->namehash = string_hash( name );
	string_copy( library->name, name, 32 );
#if FOUNDATION_PLATFORM_WINDOWS
	library->dll = dll;
#elif FOUNDATION_PLATFORM_POSIX
	library->lib = lib;
#endif
	objectmap_set( _library_map, id, library );

	error_context_pop();
	
	return library->id;
}