@@ -25,12 +25,17 @@ var caml_sys_fds = new Array(3);
2525//Provides: caml_sys_close
2626//Requires: caml_sys_fds
2727function caml_sys_close ( fd ) {
28- var file = caml_sys_fds [ fd ] ;
29- if ( file ) file . close ( ) ;
28+ var x = caml_sys_fds [ fd ] ;
29+ if ( x && x . file ) x . file . close ( ) ;
3030 delete caml_sys_fds [ fd ] ;
3131 return 0 ;
3232}
3333
34+ //Provides: MlChanid
35+ function MlChanid ( id ) {
36+ this . id = id ;
37+ }
38+
3439//Provides: caml_sys_open
3540//Requires: caml_raise_sys_error
3641//Requires: MlFakeFd_out
@@ -39,11 +44,16 @@ function caml_sys_close(fd) {
3944//Requires: fs_node_supported
4045//Requires: caml_sys_fds
4146//Requires: caml_sys_open_for_node
47+ //Requires: MlChanid
4248function caml_sys_open_internal ( file , idx ) {
49+ var chanid ;
4350 if ( idx === undefined ) {
4451 idx = caml_sys_fds . length ;
45- }
46- caml_sys_fds [ idx ] = file ;
52+ chanid = new MlChanid ( idx ) ;
53+ } else if ( caml_sys_fds [ idx ] ) {
54+ chanid = caml_sys_fds [ idx ] . chanid ;
55+ } else chanid = new MlChanid ( idx ) ;
56+ caml_sys_fds [ idx ] = { file : file , chanid : chanid } ;
4757 return idx | 0 ;
4858}
4959function caml_sys_open ( name , flags , _perms ) {
@@ -125,41 +135,59 @@ function caml_ml_set_channel_name(chanid, name) {
125135}
126136
127137//Provides: caml_ml_channels
128- var caml_ml_channels = new Array ( ) ;
138+ //Requires: MlChanid
139+ function caml_ml_channels_state ( ) {
140+ this . map = new globalThis . WeakMap ( ) ;
141+ this . opened = new globalThis . Set ( ) ;
142+ }
143+ caml_ml_channels_state . prototype . close = function ( chanid ) {
144+ this . opened . delete ( chanid ) ;
145+ } ;
146+ caml_ml_channels_state . prototype . get = function ( chanid ) {
147+ return this . map . get ( chanid ) ;
148+ } ;
149+ caml_ml_channels_state . prototype . set = function ( chanid , val ) {
150+ if ( val . opened ) this . opened . add ( chanid ) ;
151+ return this . map . set ( chanid , val ) ;
152+ } ;
153+ caml_ml_channels_state . prototype . all = function ( ) {
154+ return this . opened . values ( ) ;
155+ } ;
156+
157+ var caml_ml_channels = new caml_ml_channels_state ( ) ;
158+
159+ //Provides: caml_ml_channel_get
160+ //Requires: caml_ml_channels
161+ function caml_ml_channel_get ( id ) {
162+ return caml_ml_channels . get ( id ) ;
163+ }
129164
130165//Provides: caml_ml_channel_redirect
131166//Requires: caml_ml_channel_get, caml_ml_channels
132167function caml_ml_channel_redirect ( captured , into ) {
133168 var to_restore = caml_ml_channel_get ( captured ) ;
134169 var new_ = caml_ml_channel_get ( into ) ;
135- caml_ml_channels [ captured ] = new_ ; // XXX
170+ caml_ml_channels . set ( captured , new_ ) ;
136171 return to_restore ;
137172}
138173
139174//Provides: caml_ml_channel_restore
140175//Requires: caml_ml_channels
141176function caml_ml_channel_restore ( captured , to_restore ) {
142- caml_ml_channels [ captured ] = to_restore ; // XXX
177+ caml_ml_channels . set ( captured , to_restore ) ;
143178 return 0 ;
144179}
145180
146- //Provides: caml_ml_channel_get
147- //Requires: caml_ml_channels
148- function caml_ml_channel_get ( id ) {
149- return caml_ml_channels [ id ] ; // XXX
150- }
151-
152181//Provides: caml_ml_out_channels_list
153182//Requires: caml_ml_channels
183+ //Requires: caml_ml_channel_get
184+ //Requires: caml_sys_fds
154185function caml_ml_out_channels_list ( ) {
155186 var l = 0 ;
156- for ( var c = 0 ; c < caml_ml_channels . length ; c ++ ) {
157- if (
158- caml_ml_channels [ c ] &&
159- caml_ml_channels [ c ] . opened &&
160- caml_ml_channels [ c ] . out
161- )
162- l = [ 0 , caml_ml_channels [ c ] . fd , l ] ;
187+ var keys = caml_ml_channels . all ( ) ;
188+ for ( var k of keys ) {
189+ var chan = caml_ml_channel_get ( k ) ;
190+ if ( chan . opened && chan . out ) l = [ 0 , k , l ] ;
163191 }
164192 return l ;
165193}
@@ -169,7 +197,9 @@ function caml_ml_out_channels_list() {
169197//Requires: caml_raise_sys_error
170198//Requires: caml_sys_open
171199function caml_ml_open_descriptor_out ( fd ) {
172- var file = caml_sys_fds [ fd ] ;
200+ var s = caml_sys_fds [ fd ] ,
201+ file = s . file ,
202+ chanid = s . chanid ;
173203 if ( file . flags . rdonly ) caml_raise_sys_error ( "fd " + fd + " is readonly" ) ;
174204 var buffered = file . flags . buffered !== undefined ? file . flags . buffered : 1 ;
175205 var channel = {
@@ -182,16 +212,18 @@ function caml_ml_open_descriptor_out(fd) {
182212 buffer : new Uint8Array ( 65536 ) ,
183213 buffered : buffered ,
184214 } ;
185- caml_ml_channels [ channel . fd ] = channel ;
186- return channel . fd ;
215+ caml_ml_channels . set ( chanid , channel ) ;
216+ return chanid ;
187217}
188218
189219//Provides: caml_ml_open_descriptor_in
190220//Requires: caml_ml_channels, caml_sys_fds
191221//Requires: caml_raise_sys_error
192222//Requires: caml_sys_open
193223function caml_ml_open_descriptor_in ( fd ) {
194- var file = caml_sys_fds [ fd ] ;
224+ var s = caml_sys_fds [ fd ] ,
225+ file = s . file ,
226+ chanid = s . chanid ;
195227 if ( file . flags . wronly ) caml_raise_sys_error ( "fd " + fd + " is writeonly" ) ;
196228 var refill = null ;
197229 var channel = {
@@ -205,8 +237,8 @@ function caml_ml_open_descriptor_in(fd) {
205237 buffer : new Uint8Array ( 65536 ) ,
206238 refill : refill ,
207239 } ;
208- caml_ml_channels [ channel . fd ] = channel ;
209- return channel . fd ;
240+ caml_ml_channels . set ( chanid , channel ) ;
241+ return chanid ;
210242}
211243
212244//Provides: caml_ml_open_descriptor_in_with_flags
@@ -253,10 +285,12 @@ function caml_ml_is_binary_mode(chanid) {
253285//Provides: caml_ml_close_channel
254286//Requires: caml_ml_flush, caml_ml_channel_get
255287//Requires: caml_sys_close
288+ //Requires: caml_ml_channels
256289function caml_ml_close_channel ( chanid ) {
257290 var chan = caml_ml_channel_get ( chanid ) ;
258291 if ( chan . opened ) {
259292 chan . opened = false ;
293+ caml_ml_channels . close ( chanid ) ;
260294 caml_sys_close ( chan . fd ) ;
261295 chan . fd = - 1 ;
262296 chan . buffer = new Uint8Array ( 0 ) ;
0 commit comments