We're now going to look at adding to and removing things from the Queues. The next slide shows the beginning of the put_on_queue routine. It takes a ticket and an integer. The ticket of course refers to the Queue to which you're going to be adding something, and the integer is what you're going to be adding. The first thing you'll see there is simply the check to be sure that the ticket that was passed in actually corresponds to an index in the Queue array, rather than the array of Queues. If not, we immediately return the air and noticed that read ref already put the error message into the qe_errbuf. If it is valid we now have the index which is in Queue curve, and we go onto the next step which is to make sure that the Queue is not full. If it's full we give an error message and we give some information about how many elements you can have it in there, and return an appropriate error code. If it's not full then we go ahead and add things to the Queue in the usual way, and notice that the head count and count are not check for consistency here. That's because they were checked for consistency in read ref when the token was changed into the index, and had they been inconsistent there, you would never reach this routine because read ref would return an error. Removing an element from a Queue is a little bit different. Notice we don't pass an address of an integer variable. So, in other words we're not going to return it directly. We're going to return it through as a return value not through the parameter list. Again here we simply convert the ticket to an index, and then on the next slide we simply check to be sure that the Queue's not empty. If it is empty we give an error. If it's not empty we just grab the first element advance the head one, two. Indicate that the new head is one back, and then we simply return the element. Now, notice the "if" and the "else" both of returns. So we should never get past that "if and else." This is an example of can't happen. I can't conceive of any way this could be changed. But you never know someone may come along and change something internally. So, one of the returns only occurs under certain conditions. So, what we do here is at the bottom we have a message that basically says "Boy something's really wrong," and then we returned it internal inconsistency. So, if someone monkeys with the two return statements in such a way that one of them, that neither will be executed and forgets to add something else or deal with the failure in some way, deal with the lack of executing one of them in some way. We've now got a fail-safe they'll fall into this air buff and then the return and you'll get an internal inconsistency. Now, again why didn't we pass in a pointer to an integer variable and return the value that way? Because as it is now if the head of the Queue contains a negative number, when it returns that could be mistaken as an error. Well, the reason is as I said before how do you verify that something is actually pointing to an integer variable? You can verify it's not null. But the address may be a function pointer or something else. So, it's better to avoid that problem entirely and avoid passing pointers whenever possible. But this does leave the question of how do you disambiguate a negative value from the Queue with a negative value indicating an error? And to do that, we have to talk about how to call the removing function. Now, whenever an error occurs something is always putting qe_errbuf. Always. We can use that if no error occurs, and what's in there doesn't change, then what's in there won't change. So, we can identify that and say nothing. No the negative number is really on the Queue. Or from the Queue. But if it changes then we say that's an error. The problem is we don't know what qe_errbuf may contain before we call remove or take off. So, what we do is we clobber the first byte of qe_errbuf and put a known value in there. I use null. You can use whatever you like. Null is nice because an error message will never contain that. We then call takeoff Q. The next thing we do is check whether or not it could be an error that's ISERROR. If it's non-negative, you immediately go to the else. If it is negative, then you have to check to see whether or not errbuf was changed whether or not something was written in the errbuf. If not, then you go to the else. But if there was in the first byte will definitely be a non-null byte. Then it's an error code and you give the error message. So, that's how you do the disambiguation. For you Linux hackers that's exactly how you do the disambiguation for the system call LC.