NSCollectionViewItem lifecycle

2016-08-03 Thread Andrew Keller
Hi all,

I’m experiencing what appears to be some sort of a memory leak with my use of 
NSCollectionView.  I’ve figured out that this problem has actually always been 
happening ever since I added this particular collection view to the project; I 
just never noticed because the memory footprint of the array items was so small 
that it didn’t negatively impact the computer (and I never looked at the memory 
usage).  Well, these days, the data that our users are shoving through the app 
has grown a lot, to the point where the app now uses about 10 GB of memory 
after only about 5 minutes.  As a temporary workaround, our users can restart 
the app — but you can imagine how that gets annoying after a while.

So first, some clerical details: this is Xcode 6, on Mac OS X 10.10, using the 
old-style (pre-10.11) NSCollectionView, with an ArrayController as the data 
source to the collection view, and using bindings to hook everything up.  
Nothing is subclassed.  The elements of the ArrayController are what I call 
“Media” objects.  The ArrayController’s data source is bound to an NSArray on 
my window’s controller, and I’m using [myController setMedia:newArray] to 
change the data.  The data is never reordered, and is usually completely 
swapped out (usually, when I change the content list, it’s a wholesale total 
rewrite, and none of the objects are ever repeated).  The collection view 
serves to simply display the items visually — not much more than that.

I initially noticed the leak when my computer ran out of memory.  Some quick 
debugging revealed that my Media objects (which have a much larger memory 
footprint than they used to) are not being deallocated — ever.

According to the memory debugger in Xcode 8 (which is really awesome, by the 
way), my Media objects are being kept alive by NSCollectionViewItem objects, 
which also appear to be piling up and never deallocated.  The memory debugger 
also showed me that my view prototype is being created fresh every time — a new 
one for every cell — every time I set the media array on my controller, and the 
old cell views are also never deallocated.   Not really knowing how 
NSCollectionView works under the hood, I’m unsure of the next step to 
troubleshoot this.

Any ideas?

On a related note, what is the expected lifecycle of an NSCollectionViewItem 
object?

Thanks,
 - Andrew Keller


___

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

NSImage drawInRect deadlock

2016-08-08 Thread Andrew Keller
Hi all,

In my app, I’m creating thumbnails of images.  To do this in parallel, I’m 
using the global background dispatch queue:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 
0), ^{
@autoreleasepool {
NSSize *thumbnailSize = // calculate thumbnail size
NSImage *thumbnail = [img imageByResizingTo:thumbnailSize];
// Do stuff with result
}
});

I have this in a category extension on NSImage:

- (NSImage *)imageByResizingTo:(NSSize)newSize {
NSImage *newImage = [[NSImage alloc] initWithSize:newSize];
NSSize currentSize = [self size];
NSRect currentRect = NSMakeRect(0, 0, currentSize.width, 
currentSize.height);
NSRect newRect = NSMakeRect(0, 0, newSize.width, newSize.height);

[newImage lockFocus];
[self drawInRect:newRect fromRect:currentRect operation:NSCompositeCopy 
fraction:1.0f];
[newImage unlockFocus];

return newImage;
}

However, when enough images are being processed simultaneously, the background 
threads servicing the queue appear to all lock up with this stack trace:

#0  0x7fff93d2951a in semaphore_wait_trap ()
#1  0x7fff8b75ac5b in _os_semaphore_wait ()
#2  0x000100074e12 in _dispatch_barrier_sync_f_slow ()
#3  0x7fff89315182 in ___lldb_unnamed_function872$$RawCamera ()
#4  0x7fff86a98e26 in ImageProviderCopyImageBlockSetCallback ()
#5  0x7fff877d5279 in img_blocks_create ()
#6  0x7fff87804598 in img_blocks_extent ()
#7  0x7fff877c55b0 in img_data_lock ()
#8  0x7fff877c25a6 in CGSImageDataLock ()
#9  0x7fff8be62a02 in ripc_AcquireImage ()
#10 0x7fff8be61525 in ripc_DrawImage ()
#11 0x7fff877c21b0 in CGContextDrawImage ()
#12 0x7fff8ee9627d in __75-[NSBitmapImageRep 
_withoutChangingBackingPerformBlockUsingBackingCGImage:]_block_invoke ()
#13 0x7fff8ee95969 in -[NSBitmapImageRep 
_withoutChangingBackingPerformBlockUsingBackingCGImage:] ()
#14 0x7fff8ee958f5 in __53-[NSBitmapImageRep 
_performBlockUsingBackingCGImage:]_block_invoke ()
#15 0x7fff8ee95859 in -[NSBitmapImageRep 
_performBlockUsingBackingCGImage:] ()
#16 0x7fff8ee957b4 in -[NSBitmapImageRep CGImage] ()
#17 0x7fff8ee95719 in -[NSBitmapImageRep 
CGImageForProposedRect:context:hints:] ()
#18 0x7fff8ee4e6af in __74-[NSImageRep 
drawInRect:fromRect:operation:fraction:respectFlipped:hints:]_block_invoke ()
#19 0x7fff8ee4e195 in -[NSImageRep 
drawInRect:fromRect:operation:fraction:respectFlipped:hints:] ()
#20 0x7fff8f33e656 in __71-[NSImage 
drawInRect:fromRect:operation:fraction:respectFlipped:hints:]_block_invoke1012 
()
#21 0x7fff8edf4dc6 in -[NSImage 
_usingBestRepresentationForRect:context:hints:body:] ()
#22 0x7fff8ee4d9d7 in -[NSImage 
drawInRect:fromRect:operation:fraction:respectFlipped:hints:] ()
#23 0x00018aa5 in -[NSImage(AppKitHelpers) imageByResizingTo:] at 
/Users/kelleran/Documents/Example/Example/AppKitHelpers.m:43
[ snip ]

Then, if I try to do anything in the app such as click a button or quit the 
app, the main thread locks up too, with this stack trace:

#0  0x7fff93d2951a in semaphore_wait_trap ()
#1  0x00010006d2d5 in _dispatch_semaphore_wait_slow ()
#2  0x7fff908f4da9 in xpc_connection_send_message_with_reply_sync ()
#3  0x7fff90b1fe99 in _LSCopyApplicationInformation ()
#4  0x7fff90b29a6c in _LSCopyApplicationInformationItem ()
#5  0x7fff8ef8d08d in -[NSApplication _copyPublicPersistentUIInfo] ()
#6  0x7fff8ef8b570 in recursivelyEncodeInvalidPersistentState ()
#7  0x7fff8ef8a13a in -[NSPersistentUIManager 
flushAllChangesOptionallyWaitingUntilDone:updatingSnapshots:] ()
#8  0x7fff8ef89c6b in -[NSPersistentUIManager 
flushPersistentStateAndClose:waitingUntilDone:] ()
#9  0x7fff8ed5c466 in run_cocoa_block ()
#10 0x7fff8ef89b8e in __42-[NSPersistentUIManager 
acquireDirtyState]_block_invoke ()
#11 0x000100062fc3 in _dispatch_client_callout ()
[ snip ]

Experimentally, it seems that I need at least 10 to 20-ish threads actively 
performing work from the queue simultaneously for the deadlock to occur.  
However, just because more threads reproduces the issue faster doesn’t mean 
that fewer threads makes the problem go away entirely — it could just be a 
matter of probability and luck.  To guarantee that nothing deadlocks, must I 
perform this work serially, or is there something I’m doing wrong?

Thanks,
 - Andrew Keller

___

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: NSImage drawInRect deadlock

2016-08-09 Thread Andrew Keller
Am 08.08.2016 um 8:12 nachm. schrieb Kyle Sluder :
> 
> On Mon, Aug 8, 2016, at 05:11 PM, Jens Alfke wrote:
>> 
>>> On Aug 8, 2016, at 2:54 PM, Aaron Tuller  wrote:
>>> 
>>> "The following classes and functions are generally not thread-safe. In most 
>>> cases, you can use these classes from any thread as long as you use them 
>>> from only one thread at a time."
>> 
>> The images are only being used on one thread at a time. The problem seems
>> to be that the NSImage _cache_ is shared and (apparently) not
>> thread-safe.
> 
> I wouldn’t jump immediately to thread-unsafety. It’s possible that
> Andrew is simply exhausting the thread pool.
> 
> Andrew, are you doing anything to limit the amount of decode operations
> you’re putting on the global queue?

Not presently.  Under normal usage, it hovers around 10-40 threads, but I’ve 
seen it as high as 200.  Honestly, I was hoping to limit it to 3 or 6 — just 
experimentally, one thread by itself can saturate roughly 20-30% of my i7 
processor.  If 3-6 simultaneous operations will saturate the whole processor, I 
don’t see much value in letting it go much higher than that.

What is the preferred way to limit the number of parallel operations in the 
global queue?  I was under the impression from the docs that macOS handles the 
thread pool “automatically”.

Thanks,
 - Andrew


___

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: NSImage drawInRect deadlock

2016-08-09 Thread Andrew Keller
Am 09.08.2016 um 3:59 nachm. schrieb Kyle Sluder :
> On Tue, Aug 9, 2016, at 07:38 AM, Andrew Keller wrote:
> 
>> I was under the impression from the docs that macOS
>> handles the thread pool “automatically”.
> 
> Mike Ash did a good job explaining why this isn’t as “automatic” as one
> might think:
> https://www.mikeash.com/pyblog/friday-qa-2009-09-25-gcd-practicum.html 
> <https://www.mikeash.com/pyblog/friday-qa-2009-09-25-gcd-practicum.html>

Wow.  That was incredibly eye opening.  I’m seeing the exact same symptoms he’s 
describing — the deadlock is just the sugar on top.

I’m going to play with some of his concepts and see what happens.  I wonder if 
the deadlock can be worked around by using the image scaling approach he uses 
in his example.

Thanks,
 - Andrew

___

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: NSImage drawInRect deadlock

2016-08-09 Thread Andrew Keller
Am 09.08.2016 um 7:38 nachm. schrieb Andrew Keller :
> Am 09.08.2016 um 3:59 nachm. schrieb Kyle Sluder :
>> On Tue, Aug 9, 2016, at 07:38 AM, Andrew Keller wrote:
>> 
>>> I was under the impression from the docs that macOS
>>> handles the thread pool “automatically”.
>> 
>> Mike Ash did a good job explaining why this isn’t as “automatic” as one
>> might think:
>> https://www.mikeash.com/pyblog/friday-qa-2009-09-25-gcd-practicum.html 
>> <https://www.mikeash.com/pyblog/friday-qa-2009-09-25-gcd-practicum.html>
> 
> Wow.  That was incredibly eye opening.  I’m seeing the exact same symptoms 
> he’s describing — the deadlock is just the sugar on top.
> 
> I’m going to play with some of his concepts and see what happens.  I wonder 
> if the deadlock can be worked around by using the image scaling approach he 
> uses in his example.

A few interesting observations:

1. Mike’s thumbnail generation process is vulnerable to the same deadlock as my 
code.  In hindsight, this is not surprising since we are both using drawInRect.
2. When utilizing Mike’s approach to limiting the number of parallel tasks down 
to, say, 1-8, I have been completely unable to reproduce the deadlock.
3. When utilizing Mike’s approach to limiting the number of parallel tasks, 
Xcode is still saying that threads a being created like crazy — almost one 
thread per block submitted to the queue.

#2 suggests that this deadlock issue is related to very large (20+?  30+?  40+? 
 100+?) numbers of threads operating at the same time.

Not sure what to do about #3.  So long as it doesn’t negatively impact the app, 
I suppose I could ignore it for now.  (Unless anyone has seen this behavior, 
and perhaps foresees a problem with it.)

Thanks,
 - Andrew


___

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: NSImage drawInRect deadlock

2016-08-10 Thread Andrew Keller
Am 10.08.2016 um 2:48 vorm. schrieb Quincey Morris 
:
> On Aug 9, 2016, at 20:47 , Andrew Keller  <mailto:and...@kellerfarm.com>> wrote:
>> 
>> 2. When utilizing Mike’s approach to limiting the number of parallel tasks 
>> down to, say, 1-8, I have been completely unable to reproduce the deadlock.
>> 3. When utilizing Mike’s approach to limiting the number of parallel tasks, 
>> Xcode is still saying that threads a being created like crazy — almost one 
>> thread per block submitted to the queue.
> 
> I’m not a big fan of Mike’s proposed solution. If you want to use N-wide 
> parallelism, then use NSOperationQueue, not GCD.
> 
> Blocks dispatched to GCD queues should not contain any internal waits, such 
> as for I/O. Instead, a dispatched block should occupy the CPU continuously, 
> and at the end do one of 3 things:
> 
> 1. Just exit.
> 
> 2. Start an asynchronous action, such as GCD I/O, with a completion handler 
> that’s not scheduled until the action is done.
> 
> 3. Queue another block that represents another processing step in the overall 
> task being performed.
> 
> The point of #3 is that I think it’s also a mistake to queue large numbers of 
> blocks to GCD all at once, for the pragmatic reason that if you accidentally 
> violate the non-internal-waits rule, the size of the thread explosion depends 
> on the amount of combustible material that’s queued. It’s better for *each 
> operation* to queue its successor, and to start the whole thing off by 
> priming the pump with a modest number of blocks.
> 
> The other thing to be very careful of is global locks. If your code (perhaps 
> outside your direct control) hits any global locks that affect multiple 
> threads, *and* if the kind of lock being used is slower to test when locked 
> than when unlocked, then more parallelism can be counterproductive.
> 
> I’ve run into this in cases where adding more operations on more CPUs just 
> adds a disproportionate amount of system overhead, decreasing the throughput 
> of the actual calculation.
> 
> The point of all this is that you may not have enough control of the internal 
> behavior of those NSImage methods to safely use GCD parallelism for a job 
> like this. NSOperationQueue might be a better solution.

Interesting idea.  I’ve modified my scheduler to use existing work to post the 
next work to GCD.  This implementation has no semaphores and no custom dispatch 
queues at all.  Interestingly, I get roughly the same results: no crazy 
swapping to disk, no deadlock, and Xcode is still saying that threads are 
piling up like crazy.  (Note that I’m not letting the concurrent procedure 
count past 8)

That said, this implementation does “feel” better than before from an 
architectural point of view.  I believe I have more along the lines of 
“computationally intensive things I can do to iteratively improve the UI” 
rather than “a long list of work to do”.  Based on what the user is doing, I 
can prioritize certain parts of the UI being rendered before others, and using 
existing work to post the next work in GCD makes a lot of sense because the 
concept of “future work” can change so easily.  I know NSOperationQueue 
supports giving certain tasks priority, but I’d have to actually set all of 
those values — whereas with blocks posting other blocks, I get this behavior 
almost for free because there is always “the next most useful thing to render 
in the UI”.  If some distant future work happens to become irreverent because 
the user moved to another screen, then this approach simply never gets around 
to queueing that work, which is usually good.

Thanks,
 - Andrew

___

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

Launch, connect, communicate

2016-08-15 Thread Andrew Keller
Hi all,

In the course of normal work, I put together a really simple plotting 
application.  The problem: I’m at a command-line, and I have some numbers, and 
I want to see them on a simple plot to quickly identify patterns.  My first 
solution: A simple Cocoa app that reads the numbers on stdin, and displays them 
right on the window.  It’s simple, and it works.  At a bash shell, the usage is 
roughly: ` | 
/Applications/Plot.app/Contents/MacOS/Plot &`.  Yes, it’s crude, but it works.

Now, partially for fun and practice, and partially because this architecture is 
stopping me from making some more interesting modifications, I want to separate 
the input of the numbers from the main Plot app.  Ideally, I’d like to see a 
completely separate command-line tool that, when used, performs a series of 
steps:

1. If the main Plot app is _not_ running in the current Aqua session, then 
launch a new copy in the current Aqua session.
2. Open some sort of a socket to the main Plot app in the current Aqua session.
3. Accept numbers on stdin, and forward them through the socket to the main 
Plot app.
4. When stdin is exhausted, exit.

This architecture would, I believe, pave the way for some really neat 
improvements in the future.

So then, here comes the question.  #1 and #2 above strike me as something that 
Launch Services and/or launchd might be capable of, but I’m having trouble 
identifying a set of APIs that would perform this task.  I’ve found lots of 
documentation on having one master app delegate services to a helper that’s 
launched on-demand, but nothing yet on having _two main apps_ — one of them 
command-line and one of them Cocoa — where one can launch and subsequently 
communicate with the other, and then die.

And, for what it’s worth, I am interested in being App Store compliant.  I 
don’t know if this will make it there, but being App Store compliant is also 
something I need to learn, so I figure I may as well shoot for it.

Any ideas?

Or, are there any other mailing lists that may be more closely related to this 
topic?

Thanks,
 - Andrew Keller


___

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: Launch, connect, communicate

2016-08-19 Thread Andrew Keller
Am 16.08.2016 um 8:35 vorm. schrieb Jens Alfke :
> On Aug 15, 2016, at 7:26 PM, Andrew Keller  <mailto:and...@kellerfarm.com>> wrote:
>> 
>> 1. If the main Plot app is _not_ running in the current Aqua session, then 
>> launch a new copy in the current Aqua session.
>> 2. Open some sort of a socket to the main Plot app in the current Aqua 
>> session.
>> 3. Accept numbers on stdin, and forward them through the socket to the main 
>> Plot app.
>> 4. When stdin is exhausted, exit.
> 
> AppleEvents is the right tool for this. Just pack the numbers into an array 
> in an AEDesc, and send it in a custom AppleEvent to your app.

Interesting — Thanks, Jens.  Looks like that might work nicely for most of my 
needs.  Do you happen to know if there are any bandwidth concerns?  Eventually, 
I will be interested in streaming numbers to the main Plot app for real-time 
display.  I suspect I could simply divide the stream into hunks, and use a 
series of AppleEvents to send them.  Do you foresee any issues with that 
approach?

Thanks,
 - Andrew Keller

___

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

Machine sleep & wake notifications in a daemon

2015-01-08 Thread Andrew Keller
Good day,

I would like to receive machine sleep and wake notifications in my daemon.  In 
my Cocoa GUI application, I was able to easily follow the sample code under 
Listing 1 on the page 
<https://developer.apple.com/library/mac/qa/qa1340/_index.html>, but when I 
tried the same approach in my daemon, I received no errors or warnings from 
Xcode or in the system console, and yet the handlers also did not fire.  After 
poking around for a while, I have a hunch that it may have something to do with 
the main event queue not being the same (or existing at all?) in a non-Cocoa 
GUI application.

Is it possible to have a Cocoa-style event queue in a daemon, or is there 
another way to receive machine sleep and wake notifications from the OS in a 
daemon?

Thanks,
- Andrew Keller
___

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: Machine sleep & wake notifications in a daemon

2015-01-08 Thread Andrew Keller
On Jan 8, 2015, at 5:20 PM, Ken Thomases  wrote:

> On Jan 8, 2015, at 4:03 PM, Andrew Keller  wrote:
> 
>> I would like to receive machine sleep and wake notifications in my daemon.  
>> In my Cocoa GUI application, I was able to easily follow the sample code 
>> under Listing 1 on the page 
>> <https://developer.apple.com/library/mac/qa/qa1340/_index.html>, but when I 
>> tried the same approach in my daemon, I received no errors or warnings from 
>> Xcode or in the system console, and yet the handlers also did not fire.  
>> After poking around for a while, I have a hunch that it may have something 
>> to do with the main event queue not being the same (or existing at all?) in 
>> a non-Cocoa GUI application.
>> 
>> Is it possible to have a Cocoa-style event queue in a daemon, or is there 
>> another way to receive machine sleep and wake notifications from the OS in a 
>> daemon?
> 
> Did you read further down that QA article you linked to listings 3 and 4?

Yes.  It looks very promising, but on the first try, I wasn't able to keep the 
run loop running (it exited immediately).  I suspect that the problem has to do 
with the run loop not having any input sources.  I'm currently in the middle of 
<https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html>,
 where it's explaining how to create run loop sources.  I'm learning quite a 
lot here, but that also means that progress is very slow at the moment.  I 
figured it would hurt to ping the list to see if there was a simpler solution 
or perhaps documentation more specialized to my objective.

Also, I have a feeling that there may be something missing conceptually.  
Suppose I do manage to keep the run loop running using a new input source.  How 
do the OS and the application frameworks know to route the notification there?  
I suspect that some additional object registration may be needed to make the 
run loop handle the events, or it might be a very specific input source I don't 
know about yet...

Thanks,
 - Andrew Keller


___

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: Machine sleep & wake notifications in a daemon

2015-01-08 Thread Andrew Keller
On Jan 8, 2015, at 6:11 PM, Greg Parker  wrote:

> On Jan 8, 2015, at 2:54 PM, Andrew Keller  wrote:
> 
>> On Jan 8, 2015, at 5:20 PM, Ken Thomases  wrote:
>> 
>>> On Jan 8, 2015, at 4:03 PM, Andrew Keller  wrote:
>>> 
>>>> I would like to receive machine sleep and wake notifications in my daemon. 
>>>>  In my Cocoa GUI application, I was able to easily follow the sample code 
>>>> under Listing 1 on the page 
>>>> <https://developer.apple.com/library/mac/qa/qa1340/_index.html>, but when 
>>>> I tried the same approach in my daemon, I received no errors or warnings 
>>>> from Xcode or in the system console, and yet the handlers also did not 
>>>> fire.  After poking around for a while, I have a hunch that it may have 
>>>> something to do with the main event queue not being the same (or existing 
>>>> at all?) in a non-Cocoa GUI application.
>>>> 
>>>> Is it possible to have a Cocoa-style event queue in a daemon, or is there 
>>>> another way to receive machine sleep and wake notifications from the OS in 
>>>> a daemon?
>>> 
>>> Did you read further down that QA article you linked to listings 3 and 4?
>> 
>> Yes.  It looks very promising, but on the first try, I wasn't able to keep 
>> the run loop running (it exited immediately).  I suspect that the problem 
>> has to do with the run loop not having any input sources.  I'm currently in 
>> the middle of 
>> <https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html>,
>>  where it's explaining how to create run loop sources.  I'm learning quite a 
>> lot here, but that also means that progress is very slow at the moment.  I 
>> figured it would hurt to ping the list to see if there was a simpler 
>> solution or perhaps documentation more specialized to my objective.
>> 
>> Also, I have a feeling that there may be something missing conceptually.  
>> Suppose I do manage to keep the run loop running using a new input source.  
>> How do the OS and the application frameworks know to route the notification 
>> there?  I suspect that some additional object registration may be needed to 
>> make the run loop handle the events, or it might be a very specific input 
>> source I don't know about yet...
> 
> You shouldn't need to write your own run loop source implementation. QA1340's 
> sample code shows how it works. IORegisterForSystemPower() creates an 
> IONotificationPort that receives power notifications. 
> IONotificationPortGetRunLoopSource() creates a run loop source from that 
> notification port. CFRunLoopAddSource() adds that run loop source to the run 
> loop. Notifications sent by the OS are routed to that run loop, and when you 
> run that run loop it calls your callback function with those notifications.
> 
> You should double-check that your code is arranged the same way as QA1340's 
> code. You should also check for errors from any of those functions; perhaps 
> the notification port or run loop source is not created for some reason.

Ah!  Looks like I was being too methodical; I didn't look ahead to where the 
port is created.  (I didn't copy and paste all of the example at once; I was 
attempting to do it incrementally.)

Thanks, Ken and Greg; I'll try that when I get into work tomorrow.

Thanks,
 - Andrew Keller


___

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: Machine sleep & wake notifications in a daemon

2015-01-12 Thread Andrew Keller
On Jan 8, 2015, at 7:00 PM, Andrew Keller  wrote:

> On Jan 8, 2015, at 6:11 PM, Greg Parker  wrote:
> 
>> On Jan 8, 2015, at 2:54 PM, Andrew Keller  wrote:
>> 
>>> On Jan 8, 2015, at 5:20 PM, Ken Thomases  wrote:
>>> 
>>>> On Jan 8, 2015, at 4:03 PM, Andrew Keller  wrote:
>>>> 
>>>>> I would like to receive machine sleep and wake notifications in my 
>>>>> daemon.  In my Cocoa GUI application, I was able to easily follow the 
>>>>> sample code under Listing 1 on the page 
>>>>> <https://developer.apple.com/library/mac/qa/qa1340/_index.html>, but when 
>>>>> I tried the same approach in my daemon, I received no errors or warnings 
>>>>> from Xcode or in the system console, and yet the handlers also did not 
>>>>> fire.  After poking around for a while, I have a hunch that it may have 
>>>>> something to do with the main event queue not being the same (or existing 
>>>>> at all?) in a non-Cocoa GUI application.
>>>>> 
>>>>> Is it possible to have a Cocoa-style event queue in a daemon, or is there 
>>>>> another way to receive machine sleep and wake notifications from the OS 
>>>>> in a daemon?
>>>> 
>>>> Did you read further down that QA article you linked to listings 3 and 4?
>>> 
>>> Yes.  It looks very promising, but on the first try, I wasn't able to keep 
>>> the run loop running (it exited immediately).  I suspect that the problem 
>>> has to do with the run loop not having any input sources.  I'm currently in 
>>> the middle of 
>>> <https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html>,
>>>  where it's explaining how to create run loop sources.  I'm learning quite 
>>> a lot here, but that also means that progress is very slow at the moment.  
>>> I figured it would hurt to ping the list to see if there was a simpler 
>>> solution or perhaps documentation more specialized to my objective.
>>> 
>>> Also, I have a feeling that there may be something missing conceptually.  
>>> Suppose I do manage to keep the run loop running using a new input source.  
>>> How do the OS and the application frameworks know to route the notification 
>>> there?  I suspect that some additional object registration may be needed to 
>>> make the run loop handle the events, or it might be a very specific input 
>>> source I don't know about yet...
>> 
>> You shouldn't need to write your own run loop source implementation. 
>> QA1340's sample code shows how it works. IORegisterForSystemPower() creates 
>> an IONotificationPort that receives power notifications. 
>> IONotificationPortGetRunLoopSource() creates a run loop source from that 
>> notification port. CFRunLoopAddSource() adds that run loop source to the run 
>> loop. Notifications sent by the OS are routed to that run loop, and when you 
>> run that run loop it calls your callback function with those notifications.
>> 
>> You should double-check that your code is arranged the same way as QA1340's 
>> code. You should also check for errors from any of those functions; perhaps 
>> the notification port or run loop source is not created for some reason.
> 
> Ah!  Looks like I was being too methodical; I didn't look ahead to where the 
> port is created.  (I didn't copy and paste all of the example at once; I was 
> attempting to do it incrementally.)
> 
> Thanks, Ken and Greg; I'll try that when I get into work tomorrow.

Thanks again; everything works as expected.

One last question: Is there anything bad about using this code in a Cocoa 
application, assuming you correctly guarantee that the new run loop is not 
running on the main thread?

Thanks,
 - Andrew Keller



___

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

Human-understandable process name

2015-02-13 Thread Andrew Keller
Hello all,

I’m not sure if this is the correct list, but I figure I’ll start somewhere.

I’m writing a program that collects activity statistics on other running 
programs (in particular, network usage statistics).  I have already 
successfully harvested the statistics I want, organized by the PID and name of 
the process, however I’d like to do a better job communicating this information 
to the user.  I am intrigued by Mac OS 10.10’s ability to report “Apps using 
significant energy”; it seems to have the ability to get a commonly understood 
human-readable program name, even when the process in question is a helper app 
with a different name.  Is this ability replicable in third party applications?

Thanks,
 - Andrew Keller


___

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

Changing NSUserNotificationAlertStyle

2017-09-01 Thread Andrew Keller
Hi all,

We’re starting to wonder whether we got the default value of 
NSUserNotificationAlertStyle correct in one of our apps when we first wrote it. 
 (we thought “banner” was correct, but now we’re wondering if “alert” is better 
for this app)  Is there an intended way to change the 
NSUserNotificationAlertStyle in future versions of a specific app?

(Obviously, we can change it in our Info.plist file, but if the user has played 
with the style, how to we get the OS to reset to the default value specified by 
our Info.plist file rather than retaining the user’s previous choice?)

Then, to make matters more complicated, there’s a possibility that “alert” is 
not the correct choice for this app either, but instead we should split the 
notifications into the two apps (presumably the main app and a helper), so that 
each can use the different styles.  Is there an intended way for the two apps 
to communicate?  For example, I see that XPC services aren’t allowed to present 
UIs (not sure if that extends to NSUserNotification).

Thanks,
- Andrew Keller

___

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