NSFileHandle writeData blocking risk - objective-c

My application needs to write a short packet of data periodically to a group of TCP connections, each of which is encapsulated by an NSFileHandle. NSFileHandle offers asynchronous reading, but for writing, I think I have to use writeData (my Objective-C implementation, GNUStep, does not have the writeabilityHandler property, unfortunately).
My question is: will writeData throw an exception if the TCP file descriptor is not ready for writing, or will it block indefinitely? I've been trying to test this, but it's hard to get the other side of the connection in the proper state. The ideal thing for me would be if writeData would throw an exception, so I could try writing again later.

Related

Why page fault is considered as trap

Why page fault is considered as trap instead of interrupt?
And what exactly is the stages take place when you try access null pointer until you get segmentation fault? and the signal which is sent in this situations I SIGILL, right?
Thanks!
A trap is an exception in user-space caused by the user-space program. In this specific case the user-space program accessed a page that was not mapped using the memory management unit (MMU) and therefore caused the trap. Interrupts on the other hand are generated by external hardware events, such as a timer.

NSStream: Is there any airtight defense against blocking?

Under the Stream Programming Guide: Polling versus Run-Loop Scheduling section, the last para says:
It should be pointed out that neither the polling nor run-loop
scheduling approaches are airtight defenses against blocking. If the
NSInputStream hasBytesAvailable method or the NSOutputStream
hasSpaceAvailable method returns NO, it means in both cases that the
stream definitely has no available bytes or space. However, if either
of these methods returns YES, it can mean that there is available
bytes or space or that the only way to find out is to attempt a read
or a write operation (which could lead to a momentary block). The
NSStreamEventHasBytesAvailable and NSStreamEventHasSpaceAvailable
stream events have identical semantics.
So, it seems neither hasBytesAvailable/hasSpaceAvailable, nor stream events provide a guarantee against blocking. Is there any way to get guaranteed non-blocking behaviour with streams? I could create a background thread to get guaranteed non blocking behaviour, but I want to avoid doing that.
Also, I fail to understand why NSStream can't provide gauranteed non-blocking behaviour given that the low-level APIs (select, kqueue, etc.) can do so. Can someone explain why this is the case?
You either run your reading or writing in a different thread or you can't use NSStream. There are no other ways to get guaranteed non-blocking behavior.
For regular files and sockets you most likely will get non-blocking behavior if you schedule the stream on a runloop. But there are other types of stream that are not implemented on top of a file descriptor. By documenting the base class as not always non-blocking Apple keeps options open of implementing different streams in a way where they can't guarantee the non-blocking property.
But since we can't check the source code we can only speculate on this. You might want to file a bug with Apple requesting them to update the docs with that information.

Why does NSOperation example code uses #try & #catch

In Apple's Concurrency Programming Guide the NSOperation subclass examples (both non-concurrent and concurrent varieties) use exception handling and I'm wondering why they are encouraging this style within operations.
Listing 2-4 Responding to a cancellation request
- (void)main {
#try {
BOOL isDone = NO;
while (![self isCancelled] && !isDone) {
// Do some work and set isDone to YES when finished
}
}
#catch(...) {
// Do not rethrow exceptions.
}
}
My understanding is that generally exception handling is not a common practice in Objective-C code - exceptions are essentially programmer errors and should cause the app to crash whereas unexpected inputs are best handled by NSError. (My possibly misinformed understanding comes from things like this and this)
I'm wondering if NSOperations present a particular situation in which exception handling is important, or if this is more the preferred style of the particular author of that guide.
As a side note, some of the NSOperation example code follows this style, other examples do not. Most high-visibility OSS does not use exceptions (AFNetworking, for example).
Your understanding is correct - NSError (or similar) should be used to convey error information, rather than exceptions. Most Objective-C code is not exception-safe and will at the very least leak resources. As a general rule, never let your code leak an exception into anyone else's code - whether Apple's or a 3rd parties. Some 3rd party frameworks may explicitly indicate they are exception safe, but it's rare.
By that principle you can see why you should have a catch-all exception handler in your main method regardless. But there's actually another reason: your operation will be run on a dedicated thread. Exceptions thrown from your operation will propagate up the stack, but no further. The logical caller or owner of the operation won't get them, as they're running on a different thread (or not at all). So leaked exceptions will either kill your whole program, or be swallowed silently with no other indication. Your program may then get stuck in a weird state - since you didn't realise an error occurred, you may continue waiting for the result of your operation that will never arrive.
Additionally, Apple has a section in the Concurrency Programming Guide where they talk about Handling Errors and Exceptions. Their first point on "discrete entities" is alluding to what I said in the previous paragraph:
Handling Errors and Exceptions
Because operations are essentially
discrete entities inside your application, they are responsible for
handling any errors or exceptions that arise. In OS X v10.6 and later,
the default start method provided by the NSOperation class does not
catch exceptions. (In OS X v10.5, the start method does catch and
suppress exceptions.) Your own code should always catch and suppress
exceptions directly. It should also check error codes and notify the
appropriate parts of your application as needed. And if you replace
the start method, you must similarly catch any exceptions in your
custom implementation to prevent them from leaving the scope of the
underlying thread.
Among the types of error situations you should be prepared to handle
are the following:
Check and handle UNIX errno-style error codes.
Check explicit error
codes returned by methods and functions.
Catch exceptions thrown by
your own code or by other system frameworks.
Catch exceptions thrown
by the NSOperation class itself, which throws exceptions in the
following situations:
When the operation is not ready to execute but
its start method is called
When the operation is executing or finished
(possibly because it was canceled) and its start method is called
again
When you try to add a completion block to an operation that is
already executing or finished
When you try to retrieve the result of
an NSInvocationOperation object that was canceled
If your custom code
does encounter an exception or error, you should take whatever steps
are needed to propagate that error to the rest of your application.
The NSOperation class does not provide explicit methods for passing
along error result codes or exceptions to other parts of your
application. Therefore, if such information is important to your
application, you must provide the necessary code.
I think this post and the accompanying answer elaborates very well on the general exception- vs. no exception handling topic!
It is unsafe to throw exceptions in circumstances where resources are
not automatically managed. This is the case of the Cocoa framework
(and neighbor frameworks), as they use manual reference counting.
If you throw an exception, any release call you skip over by unwinding
the stack will result in a leak. This should limit you tothrowing only
if you're certain that you're not going to recover since all resources
are returned to the OS when a process quits.
Unfortunately, NSRunLoops tend to catch all exceptions that propagate
to them, so if you throw during an event, you'll resume to the next
event. This is, obviously, very bad. Therefore, it's better that you
simply don't throw.
This problem is diminished if you use garbage-collected Objective-C,
as any resource represented by an Objective-C object will be properly
released. However, C resources (such as file descriptors or
malloc-allocated memory) that are not wrapped in an Objective-C object
will still leak.
So, all in all, don't throw.
The Cocoa API has several workarounds to this, as you mentioned.
Returning nil and the NSError** pattern are two of them.

Good method to pass messages between embedded RTOS tasks (but can handle message timeouts gracefully)

I'm working with an embedded RTOS (CMX), but I think this applies to any embedded RTOS. I want to pass messages between various tasks. The problem is that one task sometimes 'locks' every other task out for a long period of time (several seconds).
Since I no longer wait for the message to be ACK'ed after ~100 ms or so, if I send a mailbox message during this time, the task that sent the message is no longer waiting for it reply, but the receiving task will get the message and try to act on it. The problem is that the receiving task has a pointer to the message, but since the sending task has moved on, the pointer is no longer pointing to the message which can cause huge problems.
I have no method of removing messages once they are in the queue. How can I handle this error gracefully?
This question actually covers several different issues / points.
First of all, I'm wondering why one task hogs the CPU for seconds at a time sometimes. Generally this is an indication of a design problem. But I don't know your system, and it could be that there is a reasonable explanation, so I won't go down that rabbit hole.
So from your description, you are enqueueing pointers to messages, not copies of messages. Nothing inherently wrong with that. But you can encounter exactly the problem you describe.
There are at least 2 solutions to this problem. Without knowing more, I cannot say which of these might be better.
The first approach would be to pass a copy of the message, instead of a pointer to it. For example, VxWorks msg queues (not CMX queues obviously) have you enqueue a copy of the message. I don't know if CMX supports such a model, and I don't know if you have the bandwidth / memory to support such an approach. Generally I avoid this approach when I can, but it has its place sometimes.
The second approach, which I use whenever I can in such a situation, is to have the sender allocate a message buffer (usually from my own msg/buffer pools, usually a linked-list of fixed size memory blocks - but that is an implementation detail - see this description of "memory pools" for an illustration of what I'm talking about). Anyway -- after the allocation, the sender fills in the message data, enqueues a pointer to the message, and releases control (ownership) of the memory block (i.e., the message). The receiver is now responsible for freeing/returning the memory after reading the message.
There are other issues that could be raised in this question, for example what if the sender "broadcasts" the msg to more than one receiver? How do the receivers coordinate/communicate so that only the last reader frees the memory (garbage collection)? But hopefully from what you asked, the 2nd solution will work for you.

Can the try...catch mechanism be used to avoid memory crashes?

I am really interested to know that, Is it possible that using try ... catch mechanism, we can avoid memory crash of our application ... ??
Let say the program part that we are expecting a chance of memory leak is kept under try...catch block, if the program crashes (ie memory leak) occurs then catch statement execute. So we can prevent our program from being crashed.
Is it possible ? If yes, How Or If not , why not ??
A try/catch block is there to catch an exception and stop it from propagating upwards in your callstack.
The idea goes that you catch it at the place where you know how to handle it, and then you get a chance to execute code in response to the exception.
It is not a magical solution that will prevent anything, it is just what I said above. What you do with the exception is what matters.
And a memory leak and a crash is not the same thing, it is rare that a program crashes due to memory leaks, unless it actually runs out of memory. A memory leak is rarely "fixable" after the fact. The correct, and usually only, way to fix a memory leak is to avoid it happening in the first place.
Also, yes, in a way you can keep your program from crashing by adding try/catch blocks all over, but the only thing you've succeeded in is to hide the crash from the user, and then let the program continue running. "Crashes" are not always safe to ignore, or rather, they are usually not safe to ignore.
If you are looking for some catch-all advice on how to avoid a program crashing, here's my advice:
Write a program that works correctly
I think we need to know more about what kinds of problems you're having, or you need to post a clearer question.
I would not trust any in process system to do the right thing in case of an out of memory condition. We have systems which completely lock up when a PermGen exception occurs and need a kill -9 to get rid off.
If you want the system to self correct, wrap it in a script or a system which monitors the health, a heart beat or a diagnostics page or whatever makes sense. If you receive no health indication kill it (hard if necessary) and restart it.
Best of all is to use testing and validation to include monitoring the memory (and disk) usage and make sure you really know how your system behaves and is properly configured so it does not happen.
The restarting solution is a poor alternative, because you then must test and ascertain that you can kill your application at any time and be confident it can be restarted correctly, which might even be more difficult.
If you are asking "can I catch segmentation faults with try catch", the answer is no.
try catch is for handling Objective-C exceptions i.e. those raised by executing an #throw statement. Segmentation faults caused by e.g. null pointer dereferences are generated by the operating system and are examples of Unix signals and can only be caught and handled by OS level system calls e.g. the sigaction(2) system call. Even then, the only sane thing you can do is terminate the program immediately because you might have a corrupt heap or stack.