1
0
forked from 0ad/0ad

# fix in sound resource management

.. as mentioned in
http://www.wildfiregames.com/forum/index.php?showtopic=10719&hl=
thanks to matei and philip!

bonus: refs #164
tried to alleviate that by moving the OS error bit to the very end,
which usually means it's beyond the end of the little window unless
you're looking for it. does that help?
i'll venture that the OS error *might* be useful in rare cases and it
wouldn't be bad to have in there.

This was SVN commit r4791.
This commit is contained in:
janwas 2007-01-18 22:59:44 +00:00
parent 2d98baf8e5
commit 153e607006
2 changed files with 62 additions and 30 deletions

View File

@ -553,54 +553,66 @@ const wchar_t* debug_error_message_build(
wchar_t* buf = alloc_mem(emm->alloca_buf, emm->alloca_buf_size, emm->heap_mem, max_chars);
if(!buf)
return L"(insufficient memory to generate error message)";
wchar_t* pos = buf; size_t chars_left = max_chars; int len;
char description_buf[100] = {'?'};
LibError errno_equiv = LibError_from_errno(false);
if(errno_equiv != ERR::FAIL) // meaningful translation
error_description_r(errno_equiv, description_buf, ARRAY_SIZE(description_buf));
char os_error[100];
if(sys_error_description_r(0, os_error, ARRAY_SIZE(os_error)) != INFO::OK)
strcpy_s(os_error, ARRAY_SIZE(os_error), "?");
static const wchar_t fmt[] =
// header
len = swprintf(pos, chars_left,
L"%ls\r\n"
L"Location: %hs:%d (%hs)\r\n"
L"errno = %d (%hs)\r\n"
L"OS error = %hs\r\n"
L"\r\n"
L"Call stack:\r\n"
L"\r\n";
int len = swprintf(buf,max_chars,fmt,
description,
fn_only, line, func,
errno, description_buf,
os_error
);
if(len < 0)
return L"(error while formatting error message)";
L"\r\n",
description, fn_only, line, func);
if(len < 0) goto fail; pos += len; chars_left -= len;
// add stack trace to end of message
wchar_t* pos = buf+len; const size_t chars_left = max_chars-len;
// append stack trace
if(!context)
skip += 2; // skip debug_error_message_build and debug_display_error
LibError ret = debug_dump_stack(pos, chars_left, skip, context);
if(ret == ERR::REENTERED)
{
wcscpy_s(pos, chars_left,
len = swprintf(pos, chars_left,
L"(cannot start a nested stack trace; what probably happened is that "
L"an debug_assert/debug_warn/CHECK_ERR fired during the current trace.)"
);
if(len < 0) goto fail; pos += len; chars_left -= len;
}
else if(ret != INFO::OK)
{
swprintf(pos, chars_left,
char description_buf[100] = {'?'};
len = swprintf(pos, chars_left,
L"(error while dumping stack: %hs)",
error_description_r(ret, description_buf, ARRAY_SIZE(description_buf))
);
if(len < 0) goto fail; pos += len; chars_left -= len;
}
else // success
{
len = (int)wcslen(buf);
pos = buf+len; chars_left = max_chars-len;
}
// append OS error (just in case it happens to be relevant -
// it's usually still set from unrelated operations)
char description_buf[100] = {'?'};
LibError errno_equiv = LibError_from_errno(false);
if(errno_equiv != ERR::FAIL) // meaningful translation
error_description_r(errno_equiv, description_buf, ARRAY_SIZE(description_buf));
char os_error[100];
if(sys_error_description_r(0, os_error, ARRAY_SIZE(os_error)) != INFO::OK)
strcpy_s(os_error, ARRAY_SIZE(os_error), "?");
len = swprintf(pos, chars_left,
L"\r\n"
L"errno = %d (%hs)\r\n"
L"OS error = %hs\r\n",
errno, description_buf, os_error
);
if(len < 0) goto fail; pos += len; chars_left -= len;
return buf;
fail:
return L"(error while formatting error message)";
}
static ErrorReaction call_display_error(const wchar_t* text, uint flags)

View File

@ -1070,12 +1070,16 @@ if(sd->o) ogg_release(sd->o);
#endif
}
// note: try not call this until SndData_reload is known to have succeeded.
// came up in topic#10719, "Problem freeing sounds loaded by JavaScript".
// irrespective of the h_force_free problem documented in hsd_free_all, we
// do not want to pollute hsd_list with handles that end up being freed
// (e.g. the handle was established in preparation for loading from file,
// but that load failed).
static void hsd_list_add(Handle hsd);
static LibError SndData_reload(SndData * sd, const char * fn, Handle hsd)
{
hsd_list_add(hsd);
//
// detect sound format by checking file extension
//
@ -1123,7 +1127,9 @@ static LibError SndData_reload(SndData * sd, const char * fn, Handle hsd)
WARN_RETURN(ERR::NOT_SUPPORTED);
RETURN_ERR(stream_open(&sd->s, fn));
sd->is_valid = 1;
hsd_list_add(hsd);
return INFO::OK;
}
@ -1164,11 +1170,12 @@ else
}
#endif
sd->al_buf = al_buf_alloc(al_data, al_size, sd->al_fmt, sd->al_freq);
sd->is_valid = 1;
(void)file_buf_free(file);
sd->al_buf = al_buf_alloc(al_data, al_size, sd->al_fmt, sd->al_freq);
sd->is_valid = 1;
hsd_list_add(hsd);
return INFO::OK;
}
@ -1280,6 +1287,19 @@ static void hsd_list_free_all()
// freed (list_free_all would free the source; it then releases
// its SndData reference, which closes the instance because it's
// RES_UNIQUE).
//
// NB: re-initializing the sound library (e.g. after changing
// HW settings) requires all handles to be freed, even if cached.
// hence, we use h_force_free. unfortunately this causes the
// handle's tag to be ignored. it is conceivable that the wrong
// handle could be freed here.
//
// we rule this out with the following argument. either we're
// called when re-initializing sound or at exit. in the former
// case, h_force_free does check the handle type: only sounds are
// ever freed. we don't care if the wrong one is closed since all
// must be stomped upon. in the latter case, it definitely doesn't
// matter what we free. hence, no problem.
}
// leave its memory intact, so we don't have to reallocate it later