1
1
forked from 0ad/0ad

wdetect: changed gfx_card detect to hopefully support multiple adapters (now returns the primary)

file: add timer
h_mgr bugfix: h_force_free wasn't clearing refcnt
mem: add note on shutdown order
snd: bugfixes: VSrc_validate was overzealous (al_src == 0 is allowed);
sd->is_valid wasn't being set -> leaked AL buffers.
wsdl: remove overzealous ReleaseDC check (false alarm)
gamesetup: clarify (resource) shutdown order

This was SVN commit r2913.
This commit is contained in:
janwas 2005-10-12 15:09:32 +00:00
parent dff64f6b96
commit 4285883f3d
8 changed files with 77 additions and 40 deletions

View File

@ -424,6 +424,8 @@ static bool dirent_less(const DirEnt* d1, const DirEnt* d2)
}
static TimerClient* tc_file_enum_malloc = timer_add_client("file_enum_malloc");
// call <cb> for each file and subdirectory in <dir> (alphabetical order),
// passing the entry name (not full path!), stat info, and <user>.
//
@ -468,7 +470,7 @@ int file_enum(const char* P_path, const FileCB cb, const uintptr_t user)
const size_t size = sizeof(DirEnt)+strlen(ent.name)+1;
DirEnt* p_ent;
{static TimerClient* tc = timer_add_client("file_enum_malloc"); SUM_TIMER(tc);
{SUM_TIMER(tc_file_enum_malloc);
p_ent = (DirEnt*)malloc(size);}
if(!p_ent)
{

View File

@ -856,6 +856,7 @@ int h_force_free(Handle h, H_Type type)
return ERR_INVALID_HANDLE;
u32 idx = h_idx(h);
hd->keep_open = 0;
hd->refs = 0;
return h_free_idx(idx, hd);
}
@ -908,7 +909,7 @@ int h_get_refcnt(Handle h)
void h_mgr_shutdown()
{
// close open handles
// forcibly close all open handles
for(i32 i = 0; i <= last_in_use; i++)
{
HDATA* hd = h_data_from_idx(i);

View File

@ -421,6 +421,9 @@ ssize_t mem_size(void* p)
*/
// exception to normal resource shutdown: must not be called before
// h_mgr_shutdown! (this is because h_mgr calls us to free memory, which
// requires the pointer -> Handle index still be in place)
void mem_shutdown()
{
ptr_to_h_shutdown();

View File

@ -30,10 +30,16 @@ extern void* mem_get_ptr(Handle h, size_t* size = 0);
extern int mem_get(Handle hm, u8** pp, size_t* psize);
extern Handle mem_wrap(void* p, size_t size, uint flags, void* raw_p, size_t raw_size, MEM_DTOR dtor, uintptr_t ctx);
// exception to normal resource shutdown: must not be called before
// h_mgr_shutdown! (this is because h_mgr calls us to free memory, which
// requires the pointer -> Handle index still be in place)
extern void mem_shutdown(void);
extern Handle mem_wrap(void* p, size_t size, uint flags, void* raw_p, size_t raw_size, MEM_DTOR dtor, uintptr_t ctx);
#ifdef __cplusplus

View File

@ -944,7 +944,9 @@ static int SndData_reload(SndData* sd, const char* fn, Handle hsd)
if(file_type != FT_OGG)
return -1;
return stream_open(&sd->s, fn);
RETURN_ERR(stream_open(&sd->s, fn));
sd->is_valid = 1;
return 0;
}
// else: clip
@ -992,8 +994,9 @@ else
#endif
sd->al_buf = al_buf_alloc(al_data, al_size, sd->al_fmt, sd->al_freq);
sd->is_valid = 1;
mem_free(file);
(void)mem_free(file);
return 0;
}
@ -1071,7 +1074,7 @@ static void hsd_list_free_all()
{
Handle& hsd = *it;
h_force_free(hsd, H_SndData);
(void)h_force_free(hsd, H_SndData);
// ignore errors - if hsd was a stream, and its associated source
// was active when al_shutdown was called, it will already have been
// freed (list_free_all would free the source; it then releases
@ -1298,17 +1301,16 @@ static int VSrc_reload(VSrc* vs, const char* fn, Handle hvs)
static int VSrc_validate(const VSrc* vs)
{
if(vs->al_src == 0)
return -2;
// al_src can legitimately be 0 (if vs is low-pri)
if(vs->flags & ~VS_ALL_FLAGS)
return -3;
return -2;
// no limitations on <pos>
if(!(0.0f <= vs->gain && vs->gain <= 1.0f))
return -4;
return -3;
if(!(0.0f < vs->pitch && vs->pitch <= 1.0f))
return -5;
return -4;
if(*(u8*)&vs->loop > 1 || *(u8*)&vs->relative > 1)
return -6;
return -5;
// <static_pri> and <cur_pri> have no invariant we could check.
return 0;
}

View File

@ -70,17 +70,20 @@
// EnumDisplayDevices is not available on Win95 or NT.
// try to import it manually here; return -1 if not available.
static BOOL (WINAPI *pEnumDisplayDevicesA)(void*, DWORD, void*, DWORD);
static BOOL (WINAPI *pEnumDisplayDevicesA)(LPCSTR, DWORD, LPDISPLAY_DEVICEA, DWORD);
static int import_EnumDisplayDevices()
{
if(!pEnumDisplayDevicesA)
{
static HMODULE hUser32Dll = LoadLibrary("user32.dll");
*(void**)&pEnumDisplayDevicesA = GetProcAddress(hUser32Dll, "EnumDisplayDevicesA");
// FreeLibrary(hUser32Dll);
// make sure the reference is released so BoundsChecker
// doesn't complain. it won't actually be unloaded anyway -
// there is at least one other reference.
// do not free the DLL reference! if this happens to be the first
// use of user32 (possible if it's delay-loaded or otherwise unused),
// it would actually be unloaded. that apparently breaks the
// Windows cursor.
// unfortunately there's no way to get at the reference count,
// so this resource leak is unavoidable.
}
return pEnumDisplayDevicesA? 0 : -1;
@ -120,11 +123,10 @@ int get_cur_vmode(int* xres, int* yres, int* bpp, int* freq)
// if we fail, outputs are unchanged (assumed initialized to defaults)
int get_monitor_size(int& width_mm, int& height_mm)
{
HDC dc = GetDC(0); // dc for entire screen
// (DC for the primary monitor's entire screen)
HDC dc = GetDC(0);
width_mm = GetDeviceCaps(dc, HORZSIZE);
height_mm = GetDeviceCaps(dc, VERTSIZE);
ReleaseDC(0, dc);
return 0;
}
@ -262,11 +264,26 @@ static int win_get_gfx_card()
// make sure EnumDisplayDevices is available (as pEnumDisplayDevicesA)
if(import_EnumDisplayDevices() >= 0)
{
DISPLAY_DEVICEA dev = { sizeof(dev) };
if(pEnumDisplayDevicesA(0, 0, &dev, 0))
// loop through all display adapters and put the primary device's
// identifier in gfx_card.
// (we don't bother returning a list of all of them because it's
// likely to be redundant, e.g. "Radeon" and "Radeon Secondary";
// we're only interested in the 'main' card anyway)
DISPLAY_DEVICEA dd = { sizeof(DISPLAY_DEVICEA) };
for(DWORD dev_num = 0; ; dev_num++)
{
strcpy_s(gfx_card, sizeof(gfx_card), (const char*)dev.DeviceString);
return 0;
if(!pEnumDisplayDevicesA(0, dev_num, &dd, 0))
break;
// ignore mirror pseudo-devices (installed e.g. by NetMeeting)
if(dd.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)
continue;
if(dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
{
strcpy_s(gfx_card, ARRAY_SIZE(gfx_card), (const char*)dd.DeviceString);
return 0;
}
}
}

View File

@ -663,7 +663,9 @@ static int wsdl_shutdown()
if(hDC != INVALID_HANDLE_VALUE)
{
WARN_IF_FALSE(ReleaseDC(hWnd, hDC));
// return value is whether the DC was actually freed.
// this seems to sometimes be 0, so don't warn.
(void)ReleaseDC(hWnd, hDC);
hDC = (HDC)INVALID_HANDLE_VALUE;
}

View File

@ -759,26 +759,30 @@ void Shutdown()
I18n::Shutdown();
TIMER_END("shutdown I18N");
TIMER_START("shutdown sound");
snd_shutdown();
TIMER_END("shutdown sound");
// resource
// first shut down all resource owners, and then the handle manager.
TIMER_START("resource modules");
snd_shutdown();
vfs_shutdown();
TIMER_START("shutdown vfs");
vfs_shutdown();
TIMER_END("shutdown vfs");
// this forcibly frees all open handles (thus preventing real leaks),
// and makes further access to h_mgr impossible.
h_mgr_shutdown();
// must come after h_mgr_shutdown - it causes memory to be freed,
// which requires this module to still be active.
mem_shutdown();
TIMER_END("resource modules");
TIMER_START("shutdown misc");
h_mgr_shutdown();
mem_shutdown();
file_shutdown();
file_shutdown();
timer_display_client_totals();
timer_display_client_totals();
debug_shutdown();
delete &g_Logger;
delete &g_Profiler;
// should be last, since the above use them
debug_shutdown();
delete &g_Logger;
delete &g_Profiler;
TIMER_END("shutdown misc");
}