Post

Replies

Boosts

Views

Activity

Reply to Zombie processes for terminal commands
waitid() is not documented. It is declared in the system headers, but has no man page (unlike, say, waitpid()). I'd be reluctant to use it.Also, the loop you showed will end if waitid() returns -1. How do you distinguish that from the child having exited? And why are you specifying WSTOPPED? That doesn't indicate the child has exited and won't reap the (eventual) zombie.Does it work any better to using waitpid()?
Jun ’20
Reply to dlopen not using pre-loaded dependencies (MacOS)
Yeah, I don't know if RPATH will work for you, but it's worth investigating. As I say, for each binary that's loaded, its RPATH(s) can be added to the list, and a given binary's RPATH can be relative to @loader_path or @executable_path. Now, for dependencies, as I understand it, only the RPATHs of the images leading to a specific dependency are used when searching for that dependency. (That is, if Program depends on libA and libB, libA which depends on libC, and libC depends on libD, then the RPATHs added by Program, libA, and libC are used to search for libD, but those from libB are not because it's not in the chain that leads to libD.) I'm not sure how RPATHs influence dlopen() calls, if they do.One other thing occurs to me: if the wrapper script doesn't work for all the cases you want, you could have the app process set DYLD_FALLBACK_LIBRARY_PATH and then re-exec itself with the same arguments.As you tell by the rather kludgy suggestions I'm making, you're really swimming against the tide with these requirements. 😐
May ’20
Reply to dlopen not using pre-loaded dependencies (MacOS)
The main issue is that a loaded library is not an "already-loaded dependency" unless the path from which it was loaded matches the path that dyld's search algorithm comes up with when trying to satisfy a dependency.Is there literally no relationship between the locations of plugins and the libraries on which they depend? How do you determine where things are, at run-time?The RPATH mechanism is quite flexible. It's a stack of paths that multiple components can contribute to. The executable can contribute one or more, any libraries it loads can contribute others for their dependencies, etc. That said, the only dynamism is the actual run-time location and the @executable_path and @loader_path pseudo-paths. I would think most cases could be handled by making every library install name and reference of the form @rpath/libName.dylib.If that can't be made to work, you could leave the install names as leaf names and maybe play games with the current working directory at load time. That's one part of the search algorithm that can be modified after initial process load (I think). You'd have to be careful about thread safety.Finally, it may be possible to get something like what you want by forcing the use of the flat symbol namespace and dynamic symbol lookup. You would use the -flat_namespace linker option when linking the application, the plugins, and the libraries that they depend on. Also, when linking things you would not link them against the libraries they would normally depend on. Rather, you would use the -undefined dynamic_lookup option. That would cause dyld to search through all loaded libraries to satisfy undefined symbols. This would only work if there were no symbol collisions among all of the relevant libraries. Also, it means you wouldn't catch link problems at link time, only run time.
May ’20
Reply to dlopen not using pre-loaded dependencies (MacOS)
So, the way the dynamic loader works is that it has a search algorithm that, given a library path (which might be relative), it figures out several paths to look for that library, in turn. The library will have to be found at one of those paths. It does not just match library names against already-loaded libraries. Of course, once it finds a valid path to a library, it checks if that specific library is already loaded and, if so, just increments its load count rather than loading it again.The search algorithm is described in the dlopen man page. The reference from libCommonMedia.dylib to libKayakNative.dylib appears to be just a leaf file name with no directory components in the path. For that case:"When path does not contain a slash character (i.e. it is just a leaf name), dlopen() searches the following until it finds a compatible Mach-O file: $LD_LIBRARY_PATH, $DYLD_LIBRARY_PATH, current working directory, $DYLD_FALLBACK_LIBRARY_PATH."The right way to solve this is probably to make the inter-library references use paths relative to @rpath, @executable_path, or @loader_path. (And, the RPATH can, in turn, reference @executable_path or @loader_path.) So, for example, the main application can be configured with an RPATH that includes @executable_path/../Frameworks. Then, libCommonMedia.dylib's reference to libKayakNative.dylib could be @rpath/libKayakNative.dylib or similar.
May ’20
Reply to Objects, Allocation, Theory
For what it's worth, I agree with PBK. The question you originally asked is about stuff that's almost certainly neglible. It's certainly not going to get you a 29% decrease in startup time. Fundamental design issues like reusing views instead of creating all of the (usually invisible) views for a long document is far more important. In any case, the way to figure out performance questions is to measure using Instruments or similar.Also, by the way, the code in your scenario 2 isn't feasible. The assignment to the parameter variable doesn't affect the caller's variable. You're assigning to a copy of the caller's pointer variable, not the caller's pointer variable.
May ’20
Reply to Export using Drag & Drop to Finder?
You can put a file promise on the pasteboard. If/when it is accepted, your code will be called to create the file at a particular URL.To create the file promise, instantiate and configure an NSFilePromiseProvider object. You'll need to specify a delegate object and implement the methods of NSFilePromiseProviderDelegate. Then, write the file promise to the pasteboard with the writeObjects method.There's sample code here.
Apr ’20
Reply to Block format?!?!?!
The problem is with the type of the orientation parameter of your block. Your block is using UIImageOrientation as the type, but the method you're passing it to is expecting a block that uses CGImagePropertyOrientation for that parameter.These two types are not interchangeable. So, you're going to have to change the code within the block, too. See the discussion in Apple's docs here.
Apr ’20
Reply to How to use CFBundleDisplayName for Mac apps??
You don't say what you're actually trying to accomplish. What about the user experience of your app do you want to change? (That is, why were you looking into changing CFBundleDisplay name in the first place? What were you trying to accomplish?)Also, although by default the bundle ID is based on the PRODUCT_NAME, you can change that so the bundle ID doesn't change if/when you change the PRODUCT_NAME. Just edit the Info.plist for your app and set the bundle ID directly instead of having it depend on PRODUCT_NAME.
Mar ’20
Reply to executable is killed after codesign
That's part of the purpose of the hardened runtime. By default, it won't allow an app to load an unsigned library or a library whose code signature has been invalidated because it's been modified since it's been signed.You will have to sign the modified library B. Or, you could debug with a build of A that does not have the hardened runtime enabled. Alternatively, you could debug with SIP disabled.You could add the Disable Library Validation Entitlement to A to relax the hardened runtime's restriction, but be sure you remove that for the build you ship unless you're sure you want to allow that.
Mar ’20
Reply to DispatchQueue 64 item limit?
Yes, there's a better way and, yes, there's a limit. See the Avoiding Excessive Thread Creation in the DispatchQueue documentation.The simplest tweak to your current approach is to avoid .wait(). Instead, the closure you submit to .notify() should resume processing x.txt with the current state/context and the results from y.txt. (You may need to encapsulate that state into an object separate from the work item code.) The current work item should return immediately after calling .notify(). That way, you're not blocking a thread. The thread is returned to the pool and is put to work on a task that can proceed.
Feb ’20