So this part mirrors
the queue manage of the fragile library.
Creating a queue.
The next slide shows this.
You have the index of the queue
and you're taking the space for ticket.
First thing you do is see if there's room in the array.
What happens when we delete a queue is
the right pointer will be set to null.
So we just go down the array until
we find the first one that is null.
That's where we can put our queue.
Notice that we check because
if the thing is full we want to give an error message.
This by the way should go away and
the number of queues
should be able to change dynamically.
Now, on the next slide you
allocate the queue and notice we do
the malloc and we check for an error.
We next generate the ticket
but we don't have to do it here.
We just call the Ticket ref
routine we talked about earlier.
If there's an error in that,
we simply release what we allocated.
Notice we reset it to null so we can tell whether
or not that space in the array of queues is allocated,
and then we just return the ticket.
In this case the ticket contains the error message.
Assuming that doesn't happen,
you've now got a queue.
You initialize things in the straightforward way,
and then you return the actual ticket for the queue.
Again our checklist here on the next slide is to keep
parameter list constant, consistent rather.
In general, don't pass pointers because unless you can
validate both the type and the value.
We check for array overflow
and we either report it
or we correct for it, whichever works.
We also don't trust system calls or library calls.
We check for failure there
and if they fail, we handle it.
In this case, if malloc had failed we
would have given an error message and returned.
There is an exception to this.
If you don't care whether or not the function succeeds,
then don't worry about the return value.
The best example of this is when you've opened
the file and your program
is about to exit and then you close it.
The reason it doesn't matter there is when you exit,
the system will close the file.
In that case, don't bother checking
the return value of the close function.
But if you're in a loop where
you going through many files,
then you definitely do want to check
the return value of close
because that will tell you whether or not it succeeded.
That's what I mean by when you don't
care if the function call fails.
Now, deleting a queue.
This time we get the ticket passed in.
First thing we do is
figure out whether or not it points to
a valid ticket or a valid token.
If it doesn't, when we do
the readref to pass the token that we got,
that will return an error,
and so we just return that to the cur.
If however this ticket does point to a valid queue,
now the index of the queue is in cur and
we free the elements of
the queue and then set it to null.
We set it to null as a cautionary check in case anything
goes wrong we can immediately
tell which of the queue elements are in use.
Now, question for you.
In the previous fragile program,
we talked about something called the double free
where you release space and then you re-release it,
and that as I said could
crash your program or provide a vulnerability.
So you think that you need to check whether or not
queues curve is actually valid,
but they don't. Why not?
I'll give you a minute to think about that.
The reason is this.
Let's say the ticket points to
a previously released queue.
In that case the readref will immediately
understand this and give
me an error message "No such queue."
Then I'll return the error code.
So in other words the queue is an error test.
Does that checking for us and
we don't need to do a second one.
The lessons from this. Always check
that the perimeter refers to
a valid data structure and design
your parameters so you can do this.
Second, when you delete information, clean up.
Overwrite it with no bytes if it's a string,
make it null If it's a pointer, and so forth.
That way it'll prevent errors
later on because if you try to use it or reference it,
you're either going to get an error or the program will
crash and believe me it's a lot
better for the program to crush
and go on functioning correctly.