Skip to content

Commit

Permalink
CHANGE: release port states early when possible to avoid waiting for …
Browse files Browse the repository at this point in the history
…garbage collection
  • Loading branch information
Oldes committed Oct 19, 2024
1 parent 93ff79c commit 917fe8c
Show file tree
Hide file tree
Showing 16 changed files with 248 additions and 177 deletions.
2 changes: 1 addition & 1 deletion src/core/c-handle.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
** REBOL [R3] Language Interpreter and Run-time Environment
**
** Copyright 2012 REBOL Technologies
** Copyright 2012-2023 Rebol Open Source Contributors
** Copyright 2012-2024 Rebol Open Source Contributors
** REBOL is a trademark of REBOL Technologies
**
** Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
16 changes: 15 additions & 1 deletion src/core/c-port.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
** REBOL [R3] Language Interpreter and Run-time Environment
**
** Copyright 2012 REBOL Technologies
** Copyright 2012-2023 Rebol Open Source Developers
** Copyright 2012-2024 Rebol Open Source Developers
** REBOL is a trademark of REBOL Technologies
**
** Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -435,6 +435,20 @@ xx*/ REBINT Wait_Device(REBREQ *req, REBCNT timeout)
}


FORCE_INLINE
/***********************************************************************
**
*/ void Release_Port_State(REBSER *port)
/*
** Release the request handle early, without waiting for GC
**
***********************************************************************/
{
Free_Hob(VAL_HANDLE_CTX(OFV(port, STD_PORT_STATE)));
}




/***********************************************************************
**
Expand Down
4 changes: 2 additions & 2 deletions src/core/m-pools.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
** REBOL [R3] Language Interpreter and Run-time Environment
**
** Copyright 2012 REBOL Technologies
** Copyright 2012-2021 Rebol Open Source Contributors
** Copyright 2012-2024 Rebol Open Source Contributors
** REBOL is a trademark of REBOL Technologies
**
** Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -109,7 +109,7 @@ const REBPOOLSPEC Mem_Pool_Spec[MAX_POOLS] =

DEF_POOL(sizeof(REBSER), 4096), // Series headers
DEF_POOL(sizeof(REBGOB), 128), // Gobs
DEF_POOL(sizeof(REBHOB), 512), // Handle objects
DEF_POOL(sizeof(REBHOB), 256), // Handle objects
DEF_POOL(1, 1), // Just used for tracking main memory
};

Expand Down
3 changes: 2 additions & 1 deletion src/core/p-audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
** REBOL [R3] Language Interpreter and Run-time Environment
**
** Copyright 2012 REBOL Technologies
** Copyright 2012-2023 Rebol Open Source Developers
** Copyright 2012-2024 Rebol Open Source Developers
** REBOL is a trademark of REBOL Technologies
**
** Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -134,6 +134,7 @@

case A_CLOSE:
OS_DO_DEVICE(req, RDC_CLOSE);
Release_Port_State(port);
break;

case A_OPENQ:
Expand Down
2 changes: 1 addition & 1 deletion src/core/p-checksum.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@
VAL_TAIL(ctx) = 0;
}
SET_NONE(data);
SET_CLOSED(req);
Release_Port_State(port);
}
break;

Expand Down
15 changes: 9 additions & 6 deletions src/core/p-clipboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
** REBOL [R3] Language Interpreter and Run-time Environment
**
** Copyright 2012 REBOL Technologies
** Copyright 2012-2022 Rebol Open Source Contributors
** Copyright 2012-2024 Rebol Open Source Contributors
** REBOL is a trademark of REBOL Technologies
**
** Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -44,8 +44,10 @@
REBCNT refs = 0; // refinement argument flags
REBINT len;
REBSER *ser;
REBOOL closed;

port = Validate_Port_With_Request(port_value, RDI_CLIPBOARD, &req);
closed = !IS_OPEN(req); // Keep track of whether the port was initially open

switch (action) {
case A_UPDATE:
Expand All @@ -70,7 +72,7 @@
case A_READ:
refs = Find_Refines(ds, ALL_READ_REFS);
// This device is opened on the READ:
if (!IS_OPEN(req)) {
if (closed) {
if (OS_DO_DEVICE(req, RDC_OPEN)) Trap_Port(RE_CANNOT_OPEN, port, req->error);
}

Expand Down Expand Up @@ -100,6 +102,7 @@

OS_FREE(req->data); // release the copy buffer
req->data = 0;
if (closed) Release_Port_State(port);

if (refs & AM_READ_LINES) {
Set_Block(D_RET, Split_Lines(arg));
Expand All @@ -121,7 +124,7 @@
#endif
}
// This device is opened on the WRITE:
if (!IS_OPEN(req)) {
if (closed) {
if (OS_DO_DEVICE(req, RDC_OPEN)) Trap_Port(RE_CANNOT_OPEN, port, req->error);
}

Expand Down Expand Up @@ -181,20 +184,20 @@

case A_OPEN:
if (OS_DO_DEVICE(req, RDC_OPEN)) Trap_Port(RE_CANNOT_OPEN, port, req->error);
closed = FALSE;
break;

case A_CLOSE:
OS_DO_DEVICE(req, RDC_CLOSE);
break;

case A_OPENQ:
if (IS_OPEN(req)) return R_TRUE;
return R_FALSE;
return closed ? R_FALSE : R_TRUE;

default:
Trap1(RE_NO_PORT_ACTION, Get_Action_Word(action));
}

if (closed) Release_Port_State(port);
return R_ARG1; // port
}

Expand Down
4 changes: 3 additions & 1 deletion src/core/p-dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
** REBOL [R3] Language Interpreter and Run-time Environment
**
** Copyright 2012 REBOL Technologies
** Copyright 2012-2022 Rebol Open Source Contributors
** Copyright 2012-2024 Rebol Open Source Contributors
** REBOL is a trademark of REBOL Technologies
**
** Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -289,6 +289,8 @@
Trap1(RE_NO_PORT_ACTION, Get_Action_Word(action));
}

if (!IS_OPEN(dir)) Release_Port_State(port);

return R_RET;
}

Expand Down
37 changes: 15 additions & 22 deletions src/core/p-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,22 +68,6 @@
}


/***********************************************************************
**
*/ static void Cleanup_File(REBREQ *file)
/*
***********************************************************************/
{
if (GET_FLAG(file->modes, RFM_NAME_MEM)) {
//NOTE: file->file.path will get GC'd
file->file.path = 0;
file->file.index = 0;
CLR_FLAG(file->modes, RFM_NAME_MEM);
}
SET_CLOSED(file);
}


/***********************************************************************
**
*/ static void Set_File_Date(I64 time, REBVAL *val)
Expand Down Expand Up @@ -485,6 +469,12 @@ REBINT Mode_Syms[] = {
if (IS_URL(path)) path = Obj_Value(spec, STD_PORT_SPEC_FILE_PATH);
else if (!IS_FILE(path)) Trap1(RE_INVALID_SPEC, path);

//-- Port Series Actions only called if opened as a port
if (action < A_CREATE && !IS_OPEN(file)) {
Release_Port_State(port);
Trap1(RE_NOT_OPEN, path);
}

*D_RET = *D_ARG(1);

switch (action) {
Expand All @@ -508,7 +498,7 @@ REBINT Mode_Syms[] = {
error = (REBINT)file->error; // store error value, before closing the file!
if (opened) {
OS_DO_DEVICE(file, RDC_CLOSE);
Cleanup_File(file);
Release_Port_State(port);
}

if (error) Trap_Port(RE_READ_ERROR, port, error);
Expand Down Expand Up @@ -566,7 +556,7 @@ REBINT Mode_Syms[] = {
error = (REBINT)file->error; // store error value, before closing the file!
if (opened) {
OS_DO_DEVICE(file, RDC_CLOSE);
Cleanup_File(file);
Release_Port_State(port);
}

if (error) Trap_Port(RE_WRITE_ERROR, port, error);
Expand Down Expand Up @@ -594,7 +584,7 @@ REBINT Mode_Syms[] = {
case A_CLOSE:
if (IS_OPEN(file)) {
OS_DO_DEVICE(file, RDC_CLOSE);
Cleanup_File(file);
Release_Port_State(port);
}
break;

Expand Down Expand Up @@ -642,9 +632,10 @@ REBINT Mode_Syms[] = {
if (!IS_OPEN(file)) {
Setup_File(file, 0, path);
if (OS_DO_DEVICE(file, RDC_QUERY) < 0) return R_NONE;
opened = TRUE;
}
Ret_Query_File(port, file, D_RET, D_ARG(ARG_QUERY_FIELD));
// !!! free file path?
if (opened) Release_Port_State(port);
break;

case A_MODIFY:
Expand Down Expand Up @@ -703,8 +694,10 @@ REBINT Mode_Syms[] = {
DECIDE(file->file.index > file->file.size);

case A_CLEAR:
if (!IS_OPEN(file)) Trap1(RE_NOT_OPEN, path);
// !! check for write enabled?
// The write policy is checked when the port is opened.
// When the port is opened with a read-only policy, this call
// would be silently ignored without the check below.
if(!GET_FLAG(file->modes, RFM_WRITE)) Trap1(RE_WRITE_ERROR, path);
SET_FLAG(file->modes, RFM_RESEEK);
SET_FLAG(file->modes, RFM_TRUNCATE);
file->length = 0;
Expand Down
3 changes: 2 additions & 1 deletion src/core/p-midi.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
** REBOL [R3] Language Interpreter and Run-time Environment
**
** Copyright 2012 REBOL Technologies
** Copyright 2012-2022 Rebol Open Source Developers
** Copyright 2012-2024 Rebol Open Source Developers
** REBOL is a trademark of REBOL Technologies
**
** Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -127,6 +127,7 @@
case A_CLOSE:
if (!IS_OPEN(req)) Trap_Port(RE_NOT_OPEN, port, -12);
OS_DO_DEVICE(req, RDC_CLOSE);
Release_Port_State(port);
break;

case A_QUERY:
Expand Down
5 changes: 3 additions & 2 deletions src/core/p-net.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
** REBOL [R3] Language Interpreter and Run-time Environment
**
** Copyright 2012 REBOL Technologies
** Copyright 2012-2022 Rebol Open Source Contributors
** Copyright 2012-2024 Rebol Open Source Contributors
** REBOL is a trademark of REBOL Technologies
**
** Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -360,7 +360,8 @@ enum Transport_Types {
if (OS_DO_DEVICE(sock, RDC_CLOSE) < 0) {
Trap_Port(RE_CANNOT_CLOSE, port, sock->error);
}
SET_CLOSED(sock);
//SET_CLOSED(sock);
Release_Port_State(port);
}
break;

Expand Down
4 changes: 2 additions & 2 deletions src/core/p-serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
** REBOL [R3] Language Interpreter and Run-time Environment
**
** Copyright 2013 REBOL Technologies
** Copyright 2013-2023 Rebol Open Source Developers
** Copyright 2013-2024 Rebol Open Source Developers
** REBOL is a trademark of REBOL Technologies
**
** Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -215,7 +215,7 @@
case A_CLOSE:
if (IS_OPEN(req)) {
OS_DO_DEVICE(req, RDC_CLOSE);
SET_CLOSED(req);
Release_Port_State(port);
}
break;
case A_MODIFY:
Expand Down
3 changes: 3 additions & 0 deletions src/tests/run-tests.r3
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ dt [ ;- delta time
%units/parse-test.r3
%units/percent-test.r3
%units/port-test.r3
%units/port-clipboard-test.r3
%units/port-console-test.r3
%units/port-net-test.r3
;@@ %units/port-http-test.r3 ;; temporary disabled, because httpbin.org server has serious connection issues!
%units/power-test.r3
%units/protect-test.r3
Expand Down
49 changes: 49 additions & 0 deletions src/tests/units/port-clipboard-test.r3
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
Rebol [
Title: "Rebol3 clipboard port! test script"
Author: "Oldes, Peter W A Wood"
File: %port-test.r3
Tabs: 4
Needs: [%../quick-test-module.r3]
]

~~~start-file~~~ "port"

if system/platform = 'Windows [
===start-group=== "CLIPBOARD"
;@@ https://github.com/Oldes/Rebol-issues/issues/1968
--test-- "Clipboard port test"
c: "Clipboard port test"
--assert all [
port? p: try [open clipboard://]
not error? try [write p c]
strict-equal? c try [read p]
]
close p
--test-- "Clipboard scheme test"
c: "Clipboard scheme test"
; this tests now seems to be failing when done from a run-tests script
; but is ok when done in console :-/
--assert all [
not error? try [write clipboard:// c]
strict-equal? c try [read clipboard://]
]
--test-- "issue-2486"
;@@ https://github.com/Oldes/Rebol-issues/issues/2486
foreach ch [#"a" #"^(7F)" #"^(80)" #"^(A0)"][
write clipboard:// append copy "" ch
--assert (to binary! ch) = to binary! read clipboard://
]
--test-- "Using just a name of the scheme"
;@@ https://github.com/Oldes/Rebol-issues/issues/826
txt: "hello"
--assert all [
port? try [write 'clipboard txt]
txt = try [read 'clipboard]
txt = try [read open 'clipboard]
]

===end-group===
]


~~~end-file~~~
Loading

0 comments on commit 917fe8c

Please sign in to comment.