On Sep 23, 2004, at 4:50 PM, Aaron Ballman wrote:
You cannot do any allocations whatsoever at interrupt time in Classic.
Doing so causes the your application to crash. So the short answer
is -- don't call anything that has even the most remote chance of
allocating memory, moving memory or freeing memory. If you need to do
a memory allocation, you either 1) defer the task until system time,
or 2) use interrupt-safe memory functions provided by the OS.
Well I coded something, and it seems to work on Mac OS X but one part
of it crashes on Mac OS 9. I'm not familiar with doing this kind of
thing in C, so I don't know if what I did fits in the scope of what
you're saying above. Here's what I have, commented, in the hope that a
kind soul can take 2 minutes to look at it and tell me what they think,
and who knows, it looks like I'm not the only one wrestling with this,
maybe it's going to help someone. So here goes:
// This is called by RB from my custom class
static void Foo(REALobject obj, ...)
{
// Stuff the parameters into a pointer we can pass to the parallel task
FooParams *params = (FooParams *)malloc(sizeof(FooParams));
params->object = obj;
params->... = ...
// Do the actual work in a parallel task so this function can return
// immediately and so the UI stays responsive in the REALbasic app
#if TARGET_CARBON || TARGET_PPC
MPTaskID tsk;
OSErr err = MPCreateTask(MyTask, params, 0, 0, 0, 0, 0, &tsk);
#elif TARGET_WIN32
// TODO
#endif
}
This works and looks safe to me. It returns immediately and the
MyTask() function is called.
static OSStatus MyTask(void *data)
{
// Extract the passed parameters
FooParams *params = (FooParams *)data;
REALobject obj = params->object;
... = params->...;
free(params);
// Now this is where I crash on Mac OS 9. I'm calling a function of a
private framework
// which takes another callback. This call blocks until it's done, and
the function calls
// the provided callback as it finds stuff. As I see it, I'm in a
callback here, and I'm
// calling yet another callback. Why does this crash? Even if the
callback does
// nothing (it's just an empty function), it still crashes on Mac OS
9. It works on
// Mac OS X though, no matter what I do in the callback. Any thoughts?
GoFindStuff(MyFindStuffCallback, ...);
// Now here I call an event in my REALobject to let it know that
searching is done.
// I used to call directly into RB, but since you told me I shouldn't
do this from another
// thread, I'm using a timer instead. It seems to works, on Mac OS 9
and Mac OS X.
// Is this what you meant?
DoneParams *params2 = (DoneParams *)malloc(sizeof(DoneParams));
params2->object = obj;
#if TARGET_CARBON
params2->timerUPP = NewEventLoopTimerUPP(DoneCallback);
EventLoopTimerRef timer;
InstallEventLoopTimer(GetMainEventLoop(), 0, 0, params2->timerUPP,
params2, &timer);
#elif TARGET_PPC
params2->tmTask.qLink = NULL;
params2->tmTask.qType = 0;
params2->tmTask.tmAddr = NewTimerUPP(DoneCallback);
params2->tmTask.tmCount = 0;
params2->tmTask.tmWakeUp = 0;
params2->tmTask.tmReserved = 0;
OSErr err = InstallTimeTask((QElemPtr)params2);
if (err == noErr)
PrimeTimeTask((QElemPtr)params2, 0);
#endif
return noErr;
}
static void MyFindStuffCallback(...)
{
// This can be empty, it always crashes on Mac OS 9.
// On Mac OS X I do have code here that calls back into RB, by also
installing
// a timer as in MyTask() above, and it's sweet, although this all
seems like a
// lot of work, doesn't it?
}
#if TARGET_CARBON
static pascal void DoneCallback(EventLoopTimerRef timer, void *userData)
#elif TARGET_PPC
static pascal void DoneCallback(TMTaskPtr tmTaskPtr)
#elif TARGET_WIN32
// TODO
#endif
{
// Uninstall the timer since we only needed it once
...
#if TARGET_CARBON
DoneParams *params = (DoneParams *)userData;
#elif TARGET_PPC
DoneParams *params = (DoneParams *)tmTaskPtr;
#elif TARGET_WIN32
// TODO
#endif
// Call the ServerFound event of the REALobject
ServerFoundEventProc fn = (ServerFoundEventProc)REALGetEventInstance(
(REALcontrolInstance)params->object, &ServerLookupEvents[1]);
if (fn)
fn(params->object, ...);
// Clean up
...
free(params);
}
Steve
--
Steve Roy <sroy at mac dot com>
Personal homepage: <http://homepage.mac.com/sroy>
Projects homepage: <http://www.roydesign.net>
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>
Search the archives of this list here:
<http://www.realsoftware.com/listarchives/lists.html>
|