WEBVTT

00:05.030 --> 00:10.460
So, guys, now, in order to make the code changes, in order to demonstrate deferred cancellation,

00:10.460 --> 00:16.850
what I will going to do is that I will take the last file that we edited and I will rename that file

00:16.850 --> 00:18.890
as deferred cancellation dot C.

00:22.010 --> 00:22.820
Right.

00:24.410 --> 00:30.860
So now let me open this file and let us do the code changes such that my slave threads will going to

00:30.860 --> 00:33.590
be cancelled using deferred cancellation approach.

00:33.680 --> 00:38.780
So first of all, let us find out that what is the problem with this thread?

00:38.780 --> 00:39.830
Cancellation.

00:40.100 --> 00:45.520
Despite the fact that now we have the clean up handlers to take care of resource leaking right?

00:45.530 --> 00:50.180
So using clean up handlers, we have addressed the problem of resource leaking, but still there is

00:50.180 --> 00:53.030
a problem of invariants in this thread function.

00:53.360 --> 00:55.700
Now what is the invariant problem here?

00:56.240 --> 01:02.120
Uh, unfortunately, our program is very simple that we don't make use of link list or trees.

01:02.120 --> 01:03.470
Kind of a data structure.

01:03.470 --> 01:09.360
And I have explained in one of the previous lecture video that while performing the insert, delete

01:09.360 --> 01:13.500
or update operations on those data structures may cause invariants.

01:13.500 --> 01:17.460
If the thread updating those data structures is cancelled asynchronously.

01:17.460 --> 01:18.060
Right.

01:18.390 --> 01:22.260
But still, this program too suffers from the problem of invariants.

01:22.530 --> 01:28.410
Now, with asynchronous mode of cancellation, we already know that the thread can be cancelled while

01:28.410 --> 01:31.410
executing an instruction in its execution flow.

01:31.410 --> 01:32.130
Right.

01:32.160 --> 01:39.870
So if you take a look here that our thread calls the library function called as printf, and we know

01:39.870 --> 01:45.120
that this function is internally used to format the string and write the formatted string into this

01:45.120 --> 01:46.500
buffer, right?

01:46.530 --> 01:51.300
Now, we don't know what is the internal implementation of this function, but there has to be some

01:51.300 --> 01:52.920
internal implementation.

01:52.920 --> 01:53.700
Right?

01:53.700 --> 01:59.610
And let us suppose that the internal implementation of this function is 20 lines of code, right?

02:00.520 --> 02:07.000
So it simply means that when your thread invokes this function, those 20 lines of code works behind

02:07.000 --> 02:08.500
the scenes, right?

02:08.890 --> 02:15.340
So it might be possible that if the thread cancellation signal is delivered to this thread, your thread

02:15.370 --> 02:21.520
may choose to get cancelled while executing the internal implementation of this sprintf function.

02:21.520 --> 02:22.240
Right.

02:22.240 --> 02:27.640
And the same goes with the other functions or APIs which this thread calls.

02:27.670 --> 02:32.590
Be it F right call or be it f flush call right now.

02:32.620 --> 02:39.460
F Right Call is a special call here because it is not a normal function call, but in fact it is a system

02:39.460 --> 02:40.120
call.

02:40.480 --> 02:48.790
When I say system call, it means that the internal execution of this f write call would going to execute

02:48.790 --> 02:50.290
in the kernel space.

02:50.500 --> 02:57.040
So it simply means that if your thread choose to get canceled while executing an instruction which the

02:57.040 --> 03:03.860
F write call is executing in the kernel space, then it may happen that your kernel may get corrupted.

03:03.860 --> 03:04.640
Right?

03:04.880 --> 03:11.750
It is very much possible that some logic was being executed in the kernel space and the abrupt cancellation

03:11.750 --> 03:16.070
of the thread on behalf of which that logic was being executed.

03:16.160 --> 03:23.330
And the abrupt cancellation of this thread may lead to some incomplete operation performed in the kernel

03:23.330 --> 03:28.430
space which may ultimately lead to certain corruptions or could be anything in the kernel space.

03:28.430 --> 03:29.000
Right.

03:30.050 --> 03:37.730
So I would never want my this thread to get canceled at line number 74 or line number 75 at least.

03:37.730 --> 03:38.330
Right.

03:38.450 --> 03:44.210
These are the dangerous points where if the thread gets canceled, it may lead to any undefined behavior.

03:44.420 --> 03:50.180
So therefore, in order to address the problem of invariants comes the concept of deferred cancellation

03:50.180 --> 03:51.830
that we have already discussed.

03:52.160 --> 03:59.390
I would want my thread to get cancel only at certain lines of code in my program and no other line of

03:59.390 --> 04:01.510
code as simple as that.

04:01.520 --> 04:08.060
As a developer, as a programmer, I want a complete control in my hand and I want to define that.

04:08.060 --> 04:08.450
Okay.

04:08.450 --> 04:13.820
I want my program to get canceled only at line number X, right?

04:13.820 --> 04:20.510
Because I'm -- sure that if my program canceled at line number X, then problem of invariant would

04:20.510 --> 04:21.530
not occur.

04:21.530 --> 04:22.280
Right.

04:22.640 --> 04:28.910
So currently our program make use of asynchronous mode of cancellation to convert it into deferred mode

04:28.910 --> 04:29.860
of cancellation.

04:29.870 --> 04:31.390
It would be very simple.

04:31.400 --> 04:36.230
Simply you have to specify here p thread cancel deferred.

04:36.260 --> 04:37.100
Right.

04:37.490 --> 04:42.120
So now the cancellation type of the thread has been changed to the deferred cancellation.

04:42.170 --> 04:48.080
Now coming to the cancellation point, let us suppose that every time your program wakes up from the

04:48.080 --> 04:54.320
sleep, your program would like to test whether there is any pending cancellation signal or not.

04:54.320 --> 04:59.810
So for that I would insert cancellation point at line number 78 in my program.

04:59.810 --> 05:00.500
Right.

05:00.620 --> 05:08.120
So I would insert p thread test, cancel API, call at line number 78in my function.

05:08.210 --> 05:09.050
Right.

05:09.440 --> 05:17.090
So every time the thread executes the line number 78, the thread will actually check if there is a

05:17.420 --> 05:19.580
cancellation signal which is pending.

05:19.580 --> 05:24.800
If there is a cancellation signal which is pending, then the thread will cancel right at line number

05:24.800 --> 05:25.850
78.

05:25.850 --> 05:26.630
Right.

05:27.370 --> 05:34.090
So now as a developer, I have taken a control that if my thread cancels at all, it will cancel at

05:34.090 --> 05:36.060
line number 78 only.

05:36.070 --> 05:36.850
Right.

05:36.850 --> 05:43.240
And therefore it would not cause any problem of invariant because rest of the calls in this function

05:43.270 --> 05:50.530
say as print f and f right would execute completely and they would not be and their execution would

05:50.530 --> 05:54.670
just not be canceled at any random point inside their implementation.

05:54.670 --> 05:55.420
Right.

05:55.690 --> 06:03.060
So note that whenever your thread canceled at line number 78, the cleanup handlers would work as usual.

06:03.070 --> 06:09.070
So now you can compile this program and run this program and see that it works as per our discussion.

06:09.370 --> 06:14.920
So now you can see that this is the thread function which is absolutely free from the problem of resource

06:14.920 --> 06:17.770
leaking and the problem of invariants, right?

06:18.190 --> 06:24.100
Now, there is no chance of any error whenever your thread executing this function gets canceled.

06:24.100 --> 06:24.760
Right?

06:25.120 --> 06:28.700
Our function is now fully thread cancellation safe.
