Should IOBufferMemoryDescriptor be released of free'd? - driverkit

I am looking at the documentation of IOBufferMemoryDescriptor. It says "... Except where noted, you are also responsible for releasing buffers that you allocate.".
IOBufferMemoryDescriptor::free also exists. My questions is: should I use free or release (or maybe both) to do the cleanup?

free() is called automatically when the last handle is dropped using OSSafeReleaseNULL. (This calls release() internally, but it's usually best to use the macro.)
So, never call the free() method directly, you only need to care about it in the context of overriding it in your own subclasses. Always use the reference counting mechanism on OSObject-derived classes.

Related

What are the potential repercussions of a lazy property getting initialised more than once?

The Apple doc says that
If a property marked with the lazy modifier is accessed by multiple
threads simultaneously and the property has not yet been initialized,
there is no guarantee that the property will be initialized only once.
My question is what are the potential repercussions of a property getting initialized more than once?
And in case of a property getting initialized more than once, which one of it will be used? How Swift manages them?
I went through some of the answers.
Is it normal that lazy var property is initialized twice?
But they are just saying that lazy properties can get initialized more than once. I want to know what are the repercussions of this.
Thanks in advance.
(See my comment to rmaddy's answer regarding my concern about thread-safety on writing the pointer itself. My gut is that memory corruption is not possible, but that object duplication is. But I can't prove so far from the documentation that memory corruption isn't possible.)
Object duplication is a major concern IMO if the lazy var has reference semantics. Two racing threads can get different instances:
Thread 1 begins to initialize (object A)
Thread 2 begins to initialize (object B)
Thread 1 assigns A to var and returns A to caller
Thread 2 assigns B to var and returns B to caller
This means that thread 1 and thread 2 have different instances. That definitely could be a problem if they are expecting to have the same instance. If the type has value semantics, then this shouldn't matter (that being the point of value semantics). But if it has reference semantics, then this very likely be a problem.
IMO, lazy should always be avoided if multi-threaded callers are possible. It throws uncertainty into what thread the object construction will occur on, and the last thing you want in a thread-safe object is uncertainty about what thread code will run on.
Personally I've rarely seen good use cases for lazy except for where you need to pass self in the initializer of one of your own properties. (Even then, I typically use ! types rather than lazy.) In this way, lazy is really just a kludgy work-around a Swift init headache that I wish we could solve another way, and do away with lazy, which IMO has the same "doesn't quite deliver what it promises, and so you probably have to write your own version anyway" problem as #atomic in ObjC.
The concept of "lazy initialization" is only useful if the type in question is both very expensive to construct, and unlikely to ever be used. If the variable is actually used at some point, it's slower and has less deterministic performance to make it lazy, plus it forces you to make it var when it is most often readonly.
The answer completely depends on the code you have inside the implementation of the lazy property. The biggest problem would arise from any side effects you've put in the code since they might be called more than once.
If all you do is create a self-contained object, initialize it, and return it, then there won't be any issues.
But if also do things like add a view, update an array or other data structure, or modify other properties, then you have an issue if the lazy variable is created more than once since all of those side effects will happen more than once. You end up adding two views or adding two objects to the array, etc.
Ensure that the code in your lazy property only creates and initializes an object and does not perform any other operations. If you do that, then your code won't cause any issues if the lazy property gets created multiple times from multiple threads.

POSIX mq_timedsend what happens to msg_ptr?

I am trying to debug a potential memory leak. I can see that the msg_ptr is not freed manually after the call to mq_timedsend.
My question is does mq_timedsend free the message after sending it to the queue?
No, it does not free the message, and neither should it - for any number of reasons!
The object referenced may not have been dynamically allocated in the first instance.
It cannot safely assume that the caller is no longer using the object pointed to by msg_ptr.
It cannot know that it is not a pointer to a C++ object requiring a destructor to to be called, rather than simply freeing the memory block.
In short it would be inappropriate and dangerous for any library function to behave in the way you suggest. As a general principle, dynamically allocated memory should be deleted by its owner unless there is some clear and documented protocol for ceding ownership - which is not a common pattern.
In this case the data is copied to the message queue, so you are free to modify or release whatever msg_ptr references after sending.

Retain count of the start from 4 [duplicate]

I would like to know in what situation did you use -retainCount so far, and eventually the problems that can happen using it.
Thanks.
You should never use -retainCount, because it never tells you anything useful. The implementation of the Foundation and AppKit/UIKit frameworks is opaque; you don't know what's being retained, why it's being retained, who's retaining it, when it was retained, and so on.
For example:
You'd think that [NSNumber numberWithInt:1] would have a retainCount of 1. It doesn't. It's 2.
You'd think that #"Foo" would have a retainCount of 1. It doesn't. It's 1152921504606846975.
You'd think that [NSString stringWithString:#"Foo"] would have a retainCount of 1. It doesn't. Again, it's 1152921504606846975.
Basically, since anything can retain an object (and therefore alter its retainCount), and since you don't have the source to most of the code that runs an application, an object's retainCount is meaningless.
If you're trying to track down why an object isn't getting deallocated, use the Leaks tool in Instruments. If you're trying to track down why an object was deallocated too soon, use the Zombies tool in Instruments.
But don't use -retainCount. It's a truly worthless method.
edit
Please everyone go to http://bugreport.apple.com and request that -retainCount be deprecated. The more people that ask for it, the better.
edit #2
As an update,[NSNumber numberWithInt:1] now has a retainCount of 9223372036854775807. If your code was expecting it to be 2, your code has now broken.
NEVER!
Seriously. Just don't do it.
Just follow the Memory Management Guidelines and only release what you alloc, new or copy (or anything you called retain upon originally).
#bbum said it best here on SO, and in even more detail on his blog.
Autoreleased objects are one case where checking -retainCount is uninformative and potentially misleading. The retain count tells you nothing about how many times -autorelease has been called on an object and therefore how many time it will be released when the current autorelease pool drains.
I do find retainCounts very useful when checked using 'Instruments'.
Using the 'allocations' tool, make sure 'Record reference counts' is turned on and you can go into any object and see its retainCount history.
By pairing allocs and releases you can get a good picture of what is going on and often solve those difficult cases where something is not being released.
This has never let me down - including finding bugs in early beta releases of iOS.
Take a look at the Apple documentation on NSObject, it pretty much covers your question:
NSObject retainCount
In short, retainCount is probably useless to you unless you've implemented your own reference counting system (and I can almost guarantee you won't have).
In Apple's own words, retainCount is "typically of no value in debugging memory management issues".
Of course you should never use the retainCount method in your code, since the meaning of its value depends on how many autoreleases have been applied to the object and that is something you cannot predict. However it is very useful for debugging -- especially when you are hunting down memory leaks in code that calls methods of Appkit objects outside of the main event loop -- and it should not be deprecated.
In your effort to make your point you seriously overstated the inscrutable nature of the value. It is true that it is not always a reference count. There are some special values that are used for flags, for example to indicate that an object should never be deallocated. A number like 1152921504606846975 looks very mysterious until you write it in hex and get 0xfffffffffffffff. And 9223372036854775807 is 0x7fffffffffffffff in hex. And it really is not so surprising that someone would choose to use values like these as flags, given that it would take almost 3000 years to get a retainCount as high as the larger number, assuming you incremented the retainCount 100,000,000 times per second.
What problems can you get from using it? All it does is return the retain count of the object. I have never called it and can't think of any reason that I would. I have overridden it in singletons to make sure they aren't deallocated though.
You should not be worrying about memory leaking until your app is up and running and doing something useful.
Once it is, fire up Instruments and use the app and see if memory leaks really happen. In most cases you created an object yourself (thus you own it) and forgot to release it after you were done.
Don't try and optimize your code as you are writing it, your guesses as to what may leak memory or take too long are often wrong when you actually use the app normally.
Do try and write correct code e.g. if you create an object using alloc and such, then make sure you release it properly.
Never use the -retainCount in your code. However if you use, you will never see it returns zero. Think about why. :-)
You should never use it in your code, but it could definitely help when debugging
The examples used in Dave's post are NSNumber and NSStrings...so, if you use some other classes, such as UIViews, I'm sure you will get the correct answer(The retain count depends on the implementation, and it's predictable).

Arguments and selectors

Is this:
[self showInWindow:window];
what get called after delay by this code:
[self performSelector:#selector(showInWindow:)
withObject:window
afterDelay:delay];
or am I misunderstanding the method?
Edit: the problem I'm having is that the method showInWindow get called after the delay but behaves like [self showInWindow:nil]. Any suggestion?
Yes, that's what gets called. (After the delay, of course.)
The documentation doesn't really explain what it means to "perform the selector", but what it means is exactly what you suspect.
There is one small difference between using performSelector:withObject: type methods and sending the message directly: they only work if the object is actually an object (that is, an id, a pointer to an Objective C object). But window obviously is an object.
(Strictly speaking, this isn't quite true. If you pass something that's the same size as an id or smaller, it will often work. In some cases it won't. In some cases it will work, but is illegal. In some cases, it will work and is legal but Apple strongly recommends against it. There are no cases where it's a good idea—so instead of learning the specific rules, just assume it never works. The only reason to bring this up is that this used to be common practice in Objective C back in the NeXT days, so you may occasionally still see it in other people's today.)
For more information about the performSelector: family, see the NSObject Protocol Reference, and the SO question Using -performSelector: vs. just calling the method. (For information specifically about the afterDelay: variants, see the documentation linked above.)
From the later edit to the question:
the problem I'm having is that the method showInWindow get called after the delay but behaves like [self showInWindow:nil]. Any suggestion?
First, in what way does it "behave like" the parameter is nil? Is the parameter actually nil? (Just log it in the showInWindow: implementation; if you haven't overridden the base implementation, just add an override that logs and calls the base.)
Second, if it actually is nil, was it nil at the time you sent performSelector:withObject:afterDelay:? If so, obviously it'll still be nil when the selector is sent. Also, make sure window really is an id rather than some other type. (Note that if you've got members, properties, globals, and/or locals sharing the name window, it can be confusing which one you're referring to. This is a common source of problems.)
If it's actually not nil when you schedule it, but is nil when it arrives, there are a few ways that could happen, but they're all less likely, and trickier to debug, than these two cases, so let's rule them out first.
Yes, that's what it does... Although keep in mind that it may take longer than the delay to execute. This method basically sets up an NSTimer in the current thread's run loop, so if your thread gets busy doing heavy duty work and the run loop takes longer than your delay to come back, your method will get executed later.

Asking if an object is invalid

I am trying to determine if an object is valid. The program has (at least) two threads and one of the threads might invalidate the object by removing it from an NSMutableArray. I need the other thread to check either its existence or validity before acting on it.
You can't. The only way to check if the memory your object pointer has still represents a valid object is to dereference it, but dereferencing an "invalid" object (by which I assume you mean one that has been dealloced) will result in either accessing the memory of a new object that has been allocated in the same location, garbage data that may or may not be identical to a normal object, or an unmapped memory page that will result in an immediate EXEC_BAD_ACCESS.
Any time you are holding a reference to an object you might use in the future you must retain it. If you don't you have not shown any interest or ownership in the object and the system may throw it away at any time.
Using objective C accessors and properties instead of directly setting ivars and using retain/release simplifies doing the right thing quite a bit.
Multi-threaded programming is hard. Hard does not begin to capture how difficult it is. This is the kind of hard in which a general, useable, 'reasonably qualified' way of deterministically adding two different numbers together that are being mutated and shared by multiple threads in bounded time without the use of any special assistance from the CPU in the form of atomic instructions would be a major breakthrough and the thesis of your PhD. A deity of your choice would publicly thank you for your contribution to humanity. Just for adding two numbers together. Actually, multi-threaded programming is even harder than that.
Take a look at: Technical Note TN2059
Using collection classes safely with multithreaded applications. It covers this topic in general, and outlines some of the non-obvious pitfalls that await you.
You say
I need the other thread to check either its existence or validity before acting on it.
The easiest way is to hold on to the index of the object in the NSMutableArray and then do the following
if( myObject == [myArray objectAtIndex: myObjectIndex] ) {
// everything is good !
}
else {
// my object is not what I think it is anymore
}
There are clear problem with this approach however
insertion, and deletion will stuff you up
The approach is not thread safe since the array can be changed while you are reading it
I really recomend using a different way to share this array between the two threads. Does it have to be mutable? If it doesn't then make it immutable and then you no longer have to worry about the threading issues.
If it does, then you really have to reconsider your approach. Hopefully someone can give an cocoa way of doing this in a thread safe way as I don't have the experience.