Re: NSRecursiveLock problems
Check out PLBlocks http://code.google.com/p/plblocks/ if you want to use blocks on 10.5. Cheers, Stu On Tue, Dec 22, 2009 at 12:49 PM, PCWiz pcwiz.supp...@gmail.com wrote: Well what I meant by delegates and selectors was like the secondary thread calls a selector on the main thread (using performSelectorOnMainThread) but I guess I got a little confused there :) I would like to use blocks, however I'm using the 10.5 SDK so as far as I know blocks cannot be used. Is there a way to get performSelectorOnMainThread to return a value? That would solve my issue, because I could pass on the NSAttributedString to a method on the main thread that figures out the size and all, then returns the value. Independent Cocoa Developer, Macatomy Software http://macatomy.com On 2009-12-22, at 12:22 PM, Bill Bumgarner wrote: On Dec 22, 2009, at 11:19 AM, PCWiz wrote: Is there any easy way to execute a portion of code on the main thread without going through the mess of delegates and selectors? Delegates have *nothing* to do with main thread execution. Selectors a bit orthogonal, too. If you want to execute something on the main thread, I would suggest using NSOperationQueue's notion of main queue and enqueuing an operation with a block: - (void)addOperationWithBlock:(void (^)(void))block Quite straightforward. b.bum ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/stuart.carnie%40gmail.com This email sent to stuart.car...@gmail.com -- Stuart Carnie CTO Manomio LLC In Retro We Trust! ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSRecursiveLock problems
On Dec 22, 2009, at 6:07 PM, PCWiz wrote: The issue class in my case is NSLayoutManager. I dug through the docs for NSLayoutManager and read the section on thread safety. There were 2 steps to achieving thread safety with NSLayoutManager. First, if the NSLayoutManager belonged to an NSTextView, then the text view must not be displayed while a secondary thread is making changes using its layout manager. The second part was to turn off background layout for the NSLayoutManager. In my case the layout manager was not tied to a text view (I was just using it to get the size of an attributed string) so all I had to do was this: [layoutManager setBackgroundLayoutEnabled:NO]; Those are the two criteria I specified in the release notes as being essential for using NSLayoutManager on a background thread. In general, an NSLayoutManager and associated objects can be used from only a single thread at once, but as long as you have eliminated simultaneous accesses to them from other threads, they should be OK. The tricky part is that view display and background layout will happen automatically on the main thread, so you need to make sure those will not occur for your layout manager while you are using it on a background thread. If you have done that and still see threading issues, please file a bug. Douglas Davidson ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSRecursiveLock problems
It all seems to be stable now, so turning off background layout worked :-) Thanks Independent Cocoa Developer, Macatomy Software http://macatomy.com On 2009-12-23, at 9:45 AM, Douglas Davidson wrote: On Dec 22, 2009, at 6:07 PM, PCWiz wrote: The issue class in my case is NSLayoutManager. I dug through the docs for NSLayoutManager and read the section on thread safety. There were 2 steps to achieving thread safety with NSLayoutManager. First, if the NSLayoutManager belonged to an NSTextView, then the text view must not be displayed while a secondary thread is making changes using its layout manager. The second part was to turn off background layout for the NSLayoutManager. In my case the layout manager was not tied to a text view (I was just using it to get the size of an attributed string) so all I had to do was this: [layoutManager setBackgroundLayoutEnabled:NO]; Those are the two criteria I specified in the release notes as being essential for using NSLayoutManager on a background thread. In general, an NSLayoutManager and associated objects can be used from only a single thread at once, but as long as you have eliminated simultaneous accesses to them from other threads, they should be OK. The tricky part is that view display and background layout will happen automatically on the main thread, so you need to make sure those will not occur for your layout manager while you are using it on a background thread. If you have done that and still see threading issues, please file a bug. Douglas Davidson ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSRecursiveLock problems
Glad to meet you, the DSClickableURLTextField class has been excellent :) I didn't subclass it, I just made my own little modifications to it here and there. Here is the minSizeForContent method: - (NSSize)minSizeForContent { // Grab the height for the text float newHeight = [[self attributedStringValue] heightForWidth:[self frame].size.width]; // Add 10 more pixels onto the size for safety and make new NSSize NSSize newSize = NSMakeSize([self frame].size.width, newHeight + 10.0); return newSize; } The -heightForWidth: method and several other geometrics related methods are being used from a category which can be found here: http://www.sheepsystems.com/sourceCode/sourceStringGeometrics.html The category creates its own NSTextContainer, NSTextStorage, NSLayoutManager, etc. I'm sure it would be more efficient if I used the existing layout manager in DSClickableURLTextField, haven't gotten to that yet. That might be a good feature to add in future versions, a method that performs functions similarly to what is in the category. Other modifications I made (I don't exactly remember), but I changed some things to allow for selection of the text. The issue with this is that now when you click on a link the link text returns to that default blue underline style (haven't found a way around this yet). And sure, I would love to test out the new version :-) Independent Cocoa Developer, Macatomy Software http://macatomy.com On 2009-12-23, at 6:56 PM, Michael Nickerson wrote: On Dec 23, 2009, at 2:08 PM, PCWiz wrote: It all seems to be stable now, so turning off background layout worked :-) Thanks Hey, I know you worked out what is going on, just thought I'd write you directly here. I'm the creator of the DSClickableURLTextField class. Did you subclass it and add in your own stuff for -minSizeForContent? Not that there's anything wrong with that at all (I enjoy seeing the class used!), just thought that I'd chime in and say that you don't really need to create another layout manager for this class. It already creates and uses one for tracking where the URL is when you click it, so you could just use it directly to calculate sizes. And, I actually have an updated version. I'll be posting it to my website sometime soonish, but if you'd like I can send you a copy now. New updated stuff with this version: * Fixes a bug where what the layout manager uses and what the text field shows could be slightly out of sync, * Fixes a bug where centering the text would entirely mess up where it thought the URLs were for clicking, * Now uses -setObjectValue: directly, so it should work with bindings with no extra work, * Adds in tool tips, which show the entire URL (ON by default, but can be turned off), * Adds in dragging of the URL (ON by default, but can be turned off) Also, when you copy (or drag), it now adds the URL to the pasteboard, and will go and find what the text displayed for the URL is and put that in the string pasteboard. Most applications pick up on that and display the text with the link being the URL, though some don't. At the moment there's no way to turn this off - it's one of the things I keep meaning to add in. Let me know if you'd like it, and I'll send it on. -- Darkshadow (aka Michael Nickerson) http://www.nightproductions.net ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSRecursiveLock problems
Scrap that, I managed to find where the problem is happening. Debugger: http://img709.imageshack.us/img709/9758/screenshot20091222at115.png I didn't know that NSInvocationOperation used NSRecursiveLock. But this still doesn't really help me understand *why* I'm getting these errors. The use of NSInvocationOperation seems quite simple, so I'm not seeing where this is going wrong. You can see the code where I invoke the operation in the screenshot. Independent Cocoa Developer, Macatomy Software http://macatomy.com On 2009-12-22, at 11:49 AM, PCWiz wrote: Lately I've been getting errors like these with my app: 2009-12-21 13:07:48.420 TwitMenu[2512:a0f] *** -[NSRecursiveLock unlock]: lock (NSRecursiveLock: 0x20069d980 '(null)') unlocked when not locked 2009-12-21 13:07:48.420 TwitMenu[2512:a0f] *** Break on _NSLockError() to debug. 2009-12-21 13:07:48.437 TwitMenu[2512:4103] *** -[NSRecursiveLock finalize]: lock (NSRecursiveLock: 0x20069dca0 '(null)') finalized while still in use 2009-12-21 13:07:48.437 TwitMenu[2512:4103] *** Break on _NSLockError() to debug. As Greg Parker suggested in an earlier question, instead of putting a breakpoint on NSLockError (which doesn't work) I put a breakpoint on NSLog. And this is what the debugger looks like: http://img30.imageshack.us/img30/5894/screenshot20091222at114.png I dont see how any code in there has a connection to NSRecursiveLock. Independent Cocoa Developer, Macatomy Software http://macatomy.com ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSRecursiveLock problems
Hello, NSAttributedString has proven to be unsafe in many ways for use on a secondary thread in our own applications. We were trying to do much the same thing, get the size of a string from it. But it turns out (obviously in retrospect) that it needs to use the font/GUI systems to do this, which don't seem to be safe for use on secondary threads. My guess is that it's accessing locks in the Layout manager that aren't intended to be accessed from the non-main thread and causing this error. Unless someone else has more insight than I do, you'll have to come up with an alternative way to architect this - we had to do all our string measuring on the main thread. (We were actually getting occasional crashes from doing this on a secondary thread, maybe once every 30K strings or so) Hope that helps some, Chris Backas On Dec 22, 2009, at 1:49 PM, PCWiz wrote: Lately I've been getting errors like these with my app: 2009-12-21 13:07:48.420 TwitMenu[2512:a0f] *** -[NSRecursiveLock unlock]: lock (NSRecursiveLock: 0x20069d980 '(null)') unlocked when not locked 2009-12-21 13:07:48.420 TwitMenu[2512:a0f] *** Break on _NSLockError() to debug. 2009-12-21 13:07:48.437 TwitMenu[2512:4103] *** -[NSRecursiveLock finalize]: lock (NSRecursiveLock: 0x20069dca0 '(null)') finalized while still in use 2009-12-21 13:07:48.437 TwitMenu[2512:4103] *** Break on _NSLockError() to debug. As Greg Parker suggested in an earlier question, instead of putting a breakpoint on NSLockError (which doesn't work) I put a breakpoint on NSLog. And this is what the debugger looks like: http://img30.imageshack.us/img30/5894/screenshot20091222at114.png I dont see how any code in there has a connection to NSRecursiveLock. Independent Cocoa Developer, Macatomy Software http://macatomy.com ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/chb%40infoplusonline.com This email sent to c...@infoplusonline.com ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSRecursiveLock problems
Yeah sounds like the exact same problem I'm having. The problems aren't consistent at all, it just happens once every few thousand strings. Is there any easy way to execute a portion of code on the main thread without going through the mess of delegates and selectors? Independent Cocoa Developer, Macatomy Software http://macatomy.com On 2009-12-22, at 12:06 PM, Chris Backas wrote: Hello, NSAttributedString has proven to be unsafe in many ways for use on a secondary thread in our own applications. We were trying to do much the same thing, get the size of a string from it. But it turns out (obviously in retrospect) that it needs to use the font/GUI systems to do this, which don't seem to be safe for use on secondary threads. My guess is that it's accessing locks in the Layout manager that aren't intended to be accessed from the non-main thread and causing this error. Unless someone else has more insight than I do, you'll have to come up with an alternative way to architect this - we had to do all our string measuring on the main thread. (We were actually getting occasional crashes from doing this on a secondary thread, maybe once every 30K strings or so) Hope that helps some, Chris Backas ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSRecursiveLock problems
On Dec 22, 2009, at 11:19 AM, PCWiz wrote: Is there any easy way to execute a portion of code on the main thread without going through the mess of delegates and selectors? Delegates have *nothing* to do with main thread execution. Selectors a bit orthogonal, too. If you want to execute something on the main thread, I would suggest using NSOperationQueue's notion of main queue and enqueuing an operation with a block: - (void)addOperationWithBlock:(void (^)(void))block Quite straightforward. b.bum ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSRecursiveLock problems
Well what I meant by delegates and selectors was like the secondary thread calls a selector on the main thread (using performSelectorOnMainThread) but I guess I got a little confused there :) I would like to use blocks, however I'm using the 10.5 SDK so as far as I know blocks cannot be used. Is there a way to get performSelectorOnMainThread to return a value? That would solve my issue, because I could pass on the NSAttributedString to a method on the main thread that figures out the size and all, then returns the value. Independent Cocoa Developer, Macatomy Software http://macatomy.com On 2009-12-22, at 12:22 PM, Bill Bumgarner wrote: On Dec 22, 2009, at 11:19 AM, PCWiz wrote: Is there any easy way to execute a portion of code on the main thread without going through the mess of delegates and selectors? Delegates have *nothing* to do with main thread execution. Selectors a bit orthogonal, too. If you want to execute something on the main thread, I would suggest using NSOperationQueue's notion of main queue and enqueuing an operation with a block: - (void)addOperationWithBlock:(void (^)(void))block Quite straightforward. b.bum ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSRecursiveLock problems
PCWiz wrote: I would like to use blocks, however I'm using the 10.5 SDK so as far as I know blocks cannot be used. Is there a way to get performSelectorOnMainThread to return a value? That would solve my issue, because I could pass on the NSAttributedString to a method on the main thread that figures out the size and all, then returns the value. Give performSelectorOnMainThread an object that has space for a result value. In olden days this was called a parameter block. -- GG ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSRecursiveLock problems
So for example I could do performSelectorOnMainThread with an NSMutableArray, for example, then have the method add the result object to the array and return it? Independent Cocoa Developer, Macatomy Software http://macatomy.com On 2009-12-22, at 1:29 PM, Greg Guerin wrote: I would like to use blocks, however I'm using the 10.5 SDK so as far as I know blocks cannot be used. Is there a way to get performSelectorOnMainThread to return a value? That would solve my issue, because I could pass on the NSAttributedString to a method on the main thread that figures out the size and all, then returns the value. Give performSelectorOnMainThread an object that has space for a result value. In olden days this was called a parameter block. -- GG ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSRecursiveLock problems
PCWiz wrote: So for example I could do performSelectorOnMainThread with an NSMutableArray, for example, then have the method add the result object to the array and return it? As long as no other threads were doing anything with that array, I think that would work. Or define a very simple class with a couple of properties. The obvious advantage is that a class gives you precise control over mutability, thread-safety, types, etc. -- GG ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: NSRecursiveLock problems
I think I have actually found a one line solution for this problem. The issue class in my case is NSLayoutManager. I dug through the docs for NSLayoutManager and read the section on thread safety. There were 2 steps to achieving thread safety with NSLayoutManager. First, if the NSLayoutManager belonged to an NSTextView, then the text view must not be displayed while a secondary thread is making changes using its layout manager. The second part was to turn off background layout for the NSLayoutManager. In my case the layout manager was not tied to a text view (I was just using it to get the size of an attributed string) so all I had to do was this: [layoutManager setBackgroundLayoutEnabled:NO]; And that seemed to cure it. I'm not 100% sure if the problem is gone yet, but I've left it running for about an hour, and the issue would have usually appeared by now. I'll post back if it goes wrong again. Independent Cocoa Developer, Macatomy Software http://macatomy.com On 2009-12-22, at 2:19 PM, Greg Guerin wrote: PCWiz wrote: So for example I could do performSelectorOnMainThread with an NSMutableArray, for example, then have the method add the result object to the array and return it? As long as no other threads were doing anything with that array, I think that would work. Or define a very simple class with a couple of properties. The obvious advantage is that a class gives you precise control over mutability, thread-safety, types, etc. -- GG ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/pcwiz.support%40gmail.com This email sent to pcwiz.supp...@gmail.com ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com