defer_front – can I rely on this regarding this context?

Jan 3, 2013 at 12:37am

defer_front – can I rely on this regarding this context?

Hi,

if I delete a patch dynamically using “defer_front” in the free message in one of my externals,
can I expect the “fronted” message to be executed first?
Being not sure in what order objects are deleted I’d like this to be the first thing done
when the patch gets deleted.

Is this reliable or do I have a race condition here?

Code to visualize:

void prioritized_deref(t_transport_control *x)
{
itm_dereference(x->track_itm);
}
//————————————————————————————————–
void transport_control_free(t_transport_control *x)
{
defer_front(x, (method)prioritized_deref, NULL, 0, NULL);
freeobject(x->timeobj);
}

#65889
Jan 3, 2013 at 10:48am

I do not understand why you want to use “defer_front” to such thing.

AFAIK if you want a function to be first called before the patcher is freed, and according to (as you have noticed) that there is no order guarantee, push (front or back) this function on the main queue in the object_free method will not make anything better, isn’t it ?

But a registered object can be notified by a patcher that this patcher will be freed.

object_obex_lookup(x, gensym("#P"), &x->patcher); 

if (x->patcher) {
    object_attach_byptr_register(x, x->patcher, CLASS_NOBOX);
}
Attachments:
  1. Flop.zip
#237297
Jan 3, 2013 at 11:04am

Hey Nicolas, thanks for helping

in practice using defer_front has the effect that
itm_dereference(x->track_itm);
is called before the referenced transport is deleted.
Calling itm_dereference without defer_front does somehow not work in my case.

If the transport is not dereferenced properly I’m experiencing
artefacts the next time I create a transport with the same name.

About your idea: are you sure the object receives the notification before it’s free method is called?
And aren’t notifications then send for any action regarding the patcher?

#237298
Jan 3, 2013 at 12:02pm

Hi,

I will not argue about ITM as i never used it ; but defer a function in a free method seems not obvious for me ; i suppose you have good reasons to doing that.

1. 99% (but only cycling74 dev can be 100%).
2. Various notifications are sent ; but you can parse them.

Both points are illustrated in the exemple posted above.

#237299
Jan 3, 2013 at 2:35pm

Hi Nicolas,

what you say totally makes sense but somehow makes my patch crash after creating a transport with the same name a second time. (this is the kind of crash I’m experiencing in any case not using defer_front)
I tried calling deref on “willfree” and “free”. The notify method worked correctly.

I’ll have to stick to deref_front since it turned out to be the only way that works.
Anyone an idea what’s going on?

#237300
Jan 3, 2013 at 2:36pm

crash report
–––––––––––––––––––––––––
Crashed Thread: 2

Exception Type: EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0×0000000000000014

VM Regions Near 0×14:
–> __PAGEZERO 0000000000000000-0000000000001000 [ 4K] —/— SM=NUL /Applications/Max6/Max.app/Contents/MacOS/Max
__TEXT 0000000000001000-0000000000676000 [ 6612K] rwx/rwx SM=COW /Applications/Max6/Max.app/Contents/MacOS/Max

Thread 0:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x9236e7d2 mach_msg_trap + 10
1 libsystem_kernel.dylib 0x9236dcb0 mach_msg + 68
2 com.apple.CoreFoundation 0x93cf2599 __CFRunLoopServiceMachPort + 185
3 com.apple.CoreFoundation 0x93cf7f7f __CFRunLoopRun + 1247
4 com.apple.CoreFoundation 0x93cf763a CFRunLoopRunSpecific + 378
5 com.apple.CoreFoundation 0x93cf74ab CFRunLoopRunInMode + 123
6 com.apple.HIToolbox 0x92ac815a RunCurrentEventLoopInMode + 242
7 com.apple.HIToolbox 0x92ac7ec9 ReceiveNextEventCommon + 374
8 com.apple.HIToolbox 0x92ac7d44 BlockUntilNextEventMatchingListInMode + 88
9 com.apple.AppKit 0x98b39a3a _DPSNextEvent + 724
10 com.apple.AppKit 0x98b3926c -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 119
11 com.apple.AppKit 0x98b2f6cc -[NSApplication run] + 855
12 com.cycling74.Max 0x0043270f juce::MessageManager::runDispatchLoop() + 731
13 com.cycling74.Max 0x002c1f02 juce::JUCEApplication::main(juce::StringArray const&) + 68
14 com.cycling74.Max 0x002c2025 juce::JUCEApplication::main(int, char const**) + 73
15 com.cycling74.Max 0x0000db8b _start + 209
16 com.cycling74.Max 0x0000dab9 start + 41

Thread 1:: Dispatch queue: com.apple.libdispatch-manager
0 libsystem_kernel.dylib 0x923719ae kevent + 10
1 libdispatch.dylib 0x96507c71 _dispatch_mgr_invoke + 993
2 libdispatch.dylib 0x965077a9 _dispatch_mgr_thread + 53

Thread 2 Crashed:
0 com.cycling74.Max 0x00242bbb itm_permtick + 28
1 com.cycling74.Max 0x000147a7 clock_execute + 54
2 com.cycling74.Max 0x00033ee6 sched_takepoll + 504
3 com.cycling74.Max 0x00033f36 sched_poll + 26
4 com.cycling74.Max 0×00071951 systimer_pollaction + 18
5 com.cycling74.Max 0x00071c62 mactimer_isr + 106
6 com.apple.CoreServices.CarbonCore 0x914250e0 TimerThread + 129
7 libsystem_c.dylib 0×91284557 _pthread_start + 344
8 libsystem_c.dylib 0x9126ecee thread_start + 34

Thread 3:
0 libsystem_kernel.dylib 0x923708e2 __psynch_cvwait + 10
1 libsystem_c.dylib 0×91289289 _pthread_cond_wait + 938
2 libsystem_c.dylib 0×91289512 pthread_cond_timedwait_relative_np + 47
3 com.apple.CoreServices.CarbonCore 0x9143f6ad TSWaitOnConditionTimedRelative + 177
4 com.apple.CoreServices.CarbonCore 0x9143f184 TSWaitOnSemaphoreCommon + 272
5 com.apple.CoreServices.CarbonCore 0x9143f40d TSWaitOnSemaphoreRelative + 24
6 com.apple.CoreServices.CarbonCore 0x91424ef1 DeferredTaskThread + 146
7 libsystem_c.dylib 0×91284557 _pthread_start + 344
8 libsystem_c.dylib 0x9126ecee thread_start + 34

Thread 4:
0 libsystem_kernel.dylib 0x9236e7d2 mach_msg_trap + 10
1 libsystem_kernel.dylib 0x9236dcb0 mach_msg + 68
2 com.apple.audio.midi.CoreMIDI 0x010ce22d XServerMachPort::ReceiveMessage(int&, void*, int&) + 101
3 com.apple.audio.midi.CoreMIDI 0x010ebae0 MIDIProcess::RunMIDIInThread() + 144
4 com.apple.audio.midi.CoreMIDI 0x010f1c48 MIDIProcess::MIDIInPortThread::Run() + 24
5 com.apple.audio.midi.CoreMIDI 0x010cf805 XThread::RunHelper(void*) + 17
6 com.apple.audio.midi.CoreMIDI 0x010cf2ee CAPThread::Entry(CAPThread*) + 196
7 libsystem_c.dylib 0×91284557 _pthread_start + 344
8 libsystem_c.dylib 0x9126ecee thread_start + 34

Thread 5:
0 libsystem_kernel.dylib 0x923710ee __workq_kernreturn + 10
1 libsystem_c.dylib 0x9128704c _pthread_workq_return + 45
2 libsystem_c.dylib 0x91286e19 _pthread_wqthread + 448
3 libsystem_c.dylib 0x9126ecca start_wqthread + 30

Thread 6:
0 libsystem_kernel.dylib 0x9236e8e6 mach_wait_until + 10
1 libsystem_c.dylib 0x91315c1c nanosleep + 375
2 libsystem_c.dylib 0x91315a46 usleep + 60
3 com.cycling74.Max 0x000703f5 systhread_sleep + 31
4 com.cycling74.Max 0x0023ed51 pathcache_update_do + 362
5 com.cycling74.Max 0x000704d2 systhread_threadproc + 67
6 libsystem_c.dylib 0×91284557 _pthread_start + 344
7 libsystem_c.dylib 0x9126ecee thread_start + 34

Thread 7:
0 libsystem_kernel.dylib 0x923708e2 __psynch_cvwait + 10
1 libsystem_c.dylib 0×91289220 _pthread_cond_wait + 833
2 libsystem_c.dylib 0x9130f0ec pthread_cond_timedwait$UNIX2003 + 70
3 com.cycling74.Max 0x00448be8 juce::WaitableEventImpl::wait(int) + 168
4 ??? 0×03272440 0 + 52896832
5 com.cycling74.Max 0x0043b608 juce::WaitableEvent::wait(int) const + 26
6 com.cycling74.Max 0x00455cd1 juce::Thread::wait(int) const + 27
7 com.cycling74.Max 0x0032aef0 juce::InternalTimerThread::run() + 58
8 com.cycling74.Max 0x00455bb2 juce::Thread::threadEntryPoint() + 130
9 com.cycling74.Max 0x0043953e juce::threadEntryProc(void*) + 70
10 libsystem_c.dylib 0×91284557 _pthread_start + 344
11 libsystem_c.dylib 0x9126ecee thread_start + 34

Thread 8:
0 libsystem_kernel.dylib 0x9236fe9a __accept + 10
1 com.cycling74.Max 0x0041ef4f juce::StreamingSocket::waitForNextConnection() const + 219
2 com.cycling74.Max 0x0022c571 tcpconnection_listenthread + 36
3 com.cycling74.Max 0x000704d2 systhread_threadproc + 67
4 libsystem_c.dylib 0×91284557 _pthread_start + 344
5 libsystem_c.dylib 0x9126ecee thread_start + 34

Thread 2 crashed with X86 Thread State (32-bit):
eax: 0×00000000 ebx: 0×00070000 ecx: 0x0000010d edx: 0x9128b821
edi: 0x111aabd8 esi: 0x111aa940 ebp: 0xb0288ea8 esp: 0xb0288e50
ss: 0×00000023 efl: 0×00010286 eip: 0x00242bbb cs: 0x0000001b
ds: 0×00000023 es: 0×00000023 fs: 0×00000023 gs: 0x0000000f
cr2: 0×00000014
Logical CPU: 0

#237301
Jan 3, 2013 at 2:46pm

you should free your clock, then dereference itm (forum coding):


void yourobject_free(t_yourobject *x)
{
dsp_free(x);
object_free(x->yourclock);
if (x->itm) {
object_detach_byptr(x, x->itm);
itm_dereference(x->itm);
}
}

#237302
Jan 3, 2013 at 3:41pm

The clock referenced is not created in my ext. I’m referencing a transport.
Calling (object_free(x->yourclock) //ref to transport by scriptname)
and dereferencing after that still makes Max crash.

Maybe not a clean but more safe variant: Max doesn’t crash if I don’t do any deref at all
(I found a way to get rid of the artifacts if a transport with the same name is created twice.)

Can it be harmful not to deref?

#237303
Jan 3, 2013 at 5:18pm

Hi,

IMHO for more efficient help you should implement a small external to isolate your problem and explain your code design (as it’s seems not very obvious at least for me).

#237304
Jan 3, 2013 at 6:13pm

Ok, cut down it looks like the one attached.
(At the moment no itm_deref is used)

Attachments:
  1. untitled.c
#237305

You must be logged in to reply to this topic.