1
1
-- ----------------------------------------------------------------------------
2
2
-- Ada Web Server --
3
3
-- --
4
- -- Copyright (C) 2012-2019 , AdaCore --
4
+ -- Copyright (C) 2012-2021 , AdaCore --
5
5
-- --
6
6
-- This library is free software; you can redistribute it and/or modify --
7
7
-- it under terms of the GNU General Public License as published by the --
@@ -161,10 +161,14 @@ package body AWS.Net.WebSocket.Registry is
161
161
entry Get_Socket (WebSocket : out Object_Class);
162
162
-- Get a WebSocket having some data to be sent
163
163
164
- procedure Release_Socket (WebSocket : Object_Class);
164
+ procedure Release_Socket (WebSocket : in out Object_Class);
165
165
-- Release a socket retrieved with Get_Socket above, this socket will be
166
166
-- then available again.
167
167
168
+ procedure Free (WebSocket : in out Object_Class);
169
+ -- Free WebSocket immediately if not taken by another task, otherwise
170
+ -- record it to be freed as soon as it is released.
171
+
168
172
entry Not_Empty;
169
173
-- Returns if the Set is not empty
170
174
@@ -329,7 +333,7 @@ package body AWS.Net.WebSocket.Registry is
329
333
330
334
procedure Do_Free (WebSocket : in out Object_Class) is
331
335
begin
332
- Unchecked_Free (WebSocket);
336
+ DB.Free (WebSocket);
333
337
end Do_Free ;
334
338
335
339
-- ---------------
@@ -442,7 +446,7 @@ package body AWS.Net.WebSocket.Registry is
442
446
end ;
443
447
444
448
WebSocket.Shutdown;
445
- Unchecked_Free (WebSocket);
449
+ DB.Free (WebSocket);
446
450
end if ;
447
451
end Close_To ;
448
452
@@ -499,7 +503,7 @@ package body AWS.Net.WebSocket.Registry is
499
503
Socket.On_Close (Message);
500
504
Socket.Shutdown;
501
505
502
- Unchecked_Free (W);
506
+ DB.Free (W);
503
507
end Close ;
504
508
505
509
-- --------------
@@ -516,9 +520,11 @@ package body AWS.Net.WebSocket.Registry is
516
520
-- Add watched sockets
517
521
518
522
for Id of Watched loop
519
- FD_Set.Add
520
- (Result,
521
- Registered (Id).all , Registered (Id), FD_Set.Input);
523
+ if not Registered (Id).To_Free then
524
+ FD_Set.Add
525
+ (Result,
526
+ Registered (Id).all , Registered (Id), FD_Set.Input);
527
+ end if ;
522
528
end loop ;
523
529
end return ;
524
530
end Create_Set ;
@@ -555,7 +561,7 @@ package body AWS.Net.WebSocket.Registry is
555
561
end ;
556
562
557
563
WebSocket.Shutdown;
558
- Unchecked_Free (WebSocket);
564
+ DB.Free (WebSocket);
559
565
end On_Close ;
560
566
561
567
begin
@@ -568,6 +574,24 @@ package body AWS.Net.WebSocket.Registry is
568
574
Registered.Clear;
569
575
end Finalize ;
570
576
577
+ -- --------
578
+ -- Free --
579
+ -- --------
580
+
581
+ procedure Free (WebSocket : in out Object_Class) is
582
+ begin
583
+ -- If WebSocket is in Sending it means that it has been
584
+ -- taken by the Get_Socket call. We cannot free it now, we
585
+ -- record this socket to be freed as soon as it is released
586
+ -- (Release_Socket) call.
587
+
588
+ if Sending.Contains (WebSocket.Id) then
589
+ WebSocket.To_Free := True;
590
+ else
591
+ Unchecked_Free (WebSocket);
592
+ end if ;
593
+ end Free ;
594
+
571
595
-- --------------
572
596
-- Get_Socket --
573
597
-- --------------
@@ -738,10 +762,19 @@ package body AWS.Net.WebSocket.Registry is
738
762
-- Release_Socket --
739
763
-- ------------------
740
764
741
- procedure Release_Socket (WebSocket : Object_Class) is
765
+ procedure Release_Socket (WebSocket : in out Object_Class) is
742
766
begin
743
767
Sending.Exclude (WebSocket.Id);
744
- New_Pending := True;
768
+
769
+ -- The socket has been recorded to be freed. It is not anymore
770
+ -- in the registry, we just need to free it now that it has
771
+ -- been released.
772
+
773
+ if WebSocket.To_Free then
774
+ Unchecked_Free (WebSocket);
775
+ else
776
+ New_Pending := True;
777
+ end if ;
745
778
end Release_Socket ;
746
779
747
780
-- ----------
@@ -869,15 +902,15 @@ package body AWS.Net.WebSocket.Registry is
869
902
begin
870
903
if Error = null then
871
904
DB.Unregister (W);
872
- Unchecked_Free (W);
905
+ DB.Free (W);
873
906
874
907
else
875
908
Error (W.all , A);
876
909
877
910
case A is
878
911
when Close =>
879
912
DB.Unregister (W);
880
- Unchecked_Free (W);
913
+ DB.Free (W);
881
914
when None =>
882
915
null ;
883
916
end case ;
@@ -931,9 +964,7 @@ package body AWS.Net.WebSocket.Registry is
931
964
WS.Close (Exception_Message (E), Going_Away);
932
965
WS.On_Close (Exception_Message (E));
933
966
934
- -- ??? if we free it now, there might be a reader
935
- -- in parallel that is using this socket...
936
- Unchecked_Free (WS);
967
+ DB.Free (WS);
937
968
938
969
-- No more data to send from this socket
939
970
Pending := 0 ;
@@ -996,7 +1027,7 @@ package body AWS.Net.WebSocket.Registry is
996
1027
WebSocket.Close (Exception_Message (E), Going_Away);
997
1028
998
1029
-- Do not free, it might be used by another
999
- Unchecked_Free (WebSocket);
1030
+ Free (WebSocket);
1000
1031
end ;
1001
1032
1002
1033
else
@@ -1267,7 +1298,7 @@ package body AWS.Net.WebSocket.Registry is
1267
1298
DB.Unregister (WS);
1268
1299
WebSocket_Exception
1269
1300
(WS, Exception_Message (E), Protocol_Error);
1270
- Unchecked_Free (WS);
1301
+ DB.Free (WS);
1271
1302
-- No more data to send from this socket
1272
1303
Pending := 0 ;
1273
1304
end Read_Send ;
@@ -1539,7 +1570,7 @@ package body AWS.Net.WebSocket.Registry is
1539
1570
DB.Watch (WebSocket);
1540
1571
exception
1541
1572
when others =>
1542
- Unchecked_Free (WebSocket);
1573
+ DB.Free (WebSocket);
1543
1574
raise ;
1544
1575
end Watch ;
1545
1576
0 commit comments