Re: Semaphore strangeness

2013-04-17 Thread Quincey Morris
On Apr 17, 2013, at 17:06 , Greg Parker  wrote:

> dispatch assumes you are using the semaphore in a lock-like pattern, where 
> all waiters are expected to signal when they are done with their work. In 
> that pattern, destroying a semaphore whose value is less than its original 
> value indicates a bug somewhere (because somebody should have signaled the 
> semaphore but has not yet done so). _dispatch_semaphore_dispose() is 
> enforcing that assumption and deliberately halting your process if it fails.

One example where the assumption doesn't hold is where the semaphore is 
controlling access to AudioQueueBuffers for an AudioQueue. Calling 
AudioQueueDispose suppresses further calls of the buffer release callback, 
where the semaphore is signaled. After that, you don't get any outstanding 
buffers back again, and your semaphore count is borked.

(If you try to use AudioQueueStop first, you then have to orchestrate a *wait* 
for all outstanding buffers to arrive at the callback, for no other purpose 
than satisfying the count requirement, before destroying the related semaphore. 
This adds *harder* synchronization code to solve a problem that never really 
existed.)

My assumption would be that, if you're destroying the semaphore, you're 
shutting some procedure down, so you likely have taken care of the waiters 
already. If you haven't, that's clearly a bug and they're going crash anyway 
when they try to signal a nil ivar or an invalid semaphore. There's no point in 
crashing at semaphore-disposal time.

Anyway, my workaround is now to signal the semaphore 'originalCount' times 
before disposing of it.

On Apr 17, 2013, at 17:55 , Greg Parker  wrote:

> There should be a message in the crash log.
> 
>if (dsema->dsema_value < dsema->dsema_orig) {
>DISPATCH_CLIENT_CRASH("Semaphore/group object deallocated while in 
> use");
>}


I couldn't find one. Maybe the "bad instruction" crash was a failed attempt to 
log this message?

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Semaphore strangeness

2013-04-17 Thread Greg Parker
On Apr 17, 2013, at 5:44 PM, Charles Srstka  wrote:
> On Apr 17, 2013, at 7:06 PM, Greg Parker  wrote:
>> 
>> dispatch assumes you are using the semaphore in a lock-like pattern, where 
>> all waiters are expected to signal when they are done with their work. In 
>> that pattern, destroying a semaphore whose value is less than its original 
>> value indicates a bug somewhere (because somebody should have signaled the 
>> semaphore but has not yet done so). _dispatch_semaphore_dispose() is 
>> enforcing that assumption and deliberately halting your process if it fails.
> 
> Then why not use something like an assertion or an exception which could 
> actually let the user / developer know why you crashed, instead of just 
> EXC_BAD_INSTRUCTION?

There should be a message in the crash log.

if (dsema->dsema_value < dsema->dsema_orig) {
DISPATCH_CLIENT_CRASH("Semaphore/group object deallocated while in 
use");
}


-- 
Greg Parker gpar...@apple.com Runtime Wrangler



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Semaphore strangeness

2013-04-17 Thread Charles Srstka
On Apr 17, 2013, at 7:06 PM, Greg Parker  wrote:

> On Apr 17, 2013, at 4:14 PM, Quincey Morris 
>  wrote:
> 
>> I'm not sure if this is the right list for this, but then I'm not sure what 
>> is the right list.
>> 
>> I'm seeing a consistent problem disposing of GCD semaphores. For example, if 
>> I create a semaphore like this:
>> 
>>  semaphore = dispatch_semaphore_create (10);
>> 
>> and then use if for a while, then try to destroy it (using ARC):
>> 
>>  semaphore = nil;
>> 
>> If the semaphore's count is less than the original value (10 in the 
>> example), I get a EXC_BAD_INSTRUCTION crash.
>> 
>> It's not clear to me why it should matter whether the original count has 
>> been restored. There's nothing waiting on the semaphore -- the operations 
>> that decremented the count have themselves be disposed of already.
>> 
>> If I forcibly increment the count to 10 *or more*, there's no crash.
> 
> dispatch assumes you are using the semaphore in a lock-like pattern, where 
> all waiters are expected to signal when they are done with their work. In 
> that pattern, destroying a semaphore whose value is less than its original 
> value indicates a bug somewhere (because somebody should have signaled the 
> semaphore but has not yet done so). _dispatch_semaphore_dispose() is 
> enforcing that assumption and deliberately halting your process if it fails.

Then why not use something like an assertion or an exception which could 
actually let the user / developer know why you crashed, instead of just 
EXC_BAD_INSTRUCTION?

Charles

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Semaphore strangeness

2013-04-17 Thread Greg Parker

On Apr 17, 2013, at 4:14 PM, Quincey Morris 
 wrote:

> I'm not sure if this is the right list for this, but then I'm not sure what 
> is the right list.
> 
> I'm seeing a consistent problem disposing of GCD semaphores. For example, if 
> I create a semaphore like this:
> 
>   semaphore = dispatch_semaphore_create (10);
> 
> and then use if for a while, then try to destroy it (using ARC):
> 
>   semaphore = nil;
> 
> If the semaphore's count is less than the original value (10 in the example), 
> I get a EXC_BAD_INSTRUCTION crash.
> 
> It's not clear to me why it should matter whether the original count has been 
> restored. There's nothing waiting on the semaphore -- the operations that 
> decremented the count have themselves be disposed of already.
> 
> If I forcibly increment the count to 10 *or more*, there's no crash.

dispatch assumes you are using the semaphore in a lock-like pattern, where all 
waiters are expected to signal when they are done with their work. In that 
pattern, destroying a semaphore whose value is less than its original value 
indicates a bug somewhere (because somebody should have signaled the semaphore 
but has not yet done so). _dispatch_semaphore_dispose() is enforcing that 
assumption and deliberately halting your process if it fails.


-- 
Greg Parker gpar...@apple.com Runtime Wrangler



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Semaphore strangeness

2013-04-17 Thread Quincey Morris
I'm not sure if this is the right list for this, but then I'm not sure what is 
the right list.

I'm seeing a consistent problem disposing of GCD semaphores. For example, if I 
create a semaphore like this:

semaphore = dispatch_semaphore_create (10);

and then use if for a while, then try to destroy it (using ARC):

semaphore = nil;

If the semaphore's count is less than the original value (10 in the example), I 
get a EXC_BAD_INSTRUCTION crash:

> #0  0x7fff91fcfb5f in _dispatch_semaphore_dispose ()
> #1  0x7fff91fcc898 in _dispatch_dispose ()
> #2  0x7fff91fcc837 in -[OS_dispatch_object _xref_dispose] ()

> 0x7fff91fcfb3e  <+>  push   %rbp
> 0x7fff91fcfb3f  <+0001>  mov%rsp,%rbp
> 0x7fff91fcfb42  <+0004>  push   %rbx
> 0x7fff91fcfb43  <+0005>  push   %rax
> 0x7fff91fcfb44  <+0006>  mov%rdi,%rbx
> 0x7fff91fcfb47  <+0009>  mov0x38(%rbx),%rax
> 0x7fff91fcfb4b  <+0013>  cmp0x40(%rbx),%rax
> 0x7fff91fcfb4f  <+0017>  jge0x7fff91fcfb61 
> <_dispatch_semaphore_dispose+35>
> 0x7fff91fcfb51  <+0019>  lea0xa8a6(%rip),%rcx# 0x7fff91fda3fe
> 0x7fff91fcfb58  <+0026>  mov%rcx,-0x17cbe317(%rip)# 
> 0x7fff7a311848 
> 0x7fff91fcfb5f  <+0033>  ud2a   << Thread 1: Program received signal: 
> 'EXC_BAD_INSTRUCTION'

It's not clear to me why it should matter whether the original count has been 
restored. There's nothing waiting on the semaphore -- the operations that 
decremented the count have themselves be disposed of already.

If I forcibly increment the count to 10 *or more*, there's no crash.



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com