From 17936a14edbb264cd18c136951109b63cea4bf21 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sun, 11 Dec 2022 22:01:29 -0600 Subject: [PATCH] Rework root file code for CDevs to avoid leaking user IDs. Formerly, the code would allocate user IDs but never free them. The result was that one user ID was leaked for each time a CDev was opened and closed. The new root code calls new cleanup code in ORCALib, which detects if the CDev is going away and deallocates its user ID if so. --- Native.pas | 46 ++++++++++++++++++++++++++-------------------- cc.notes | 2 ++ 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/Native.pas b/Native.pas index 82abe86..dcf4676 100644 --- a/Native.pas +++ b/Native.pas @@ -2456,29 +2456,35 @@ procedure InitFile {keepName: gsosOutStringPtr; keepFlag: integer; partial: bool {control panel device initialization} else if isCDev then begin - CnOut(m_pea); - CnOut2(1); + CnOut(m_phb); {save data bank} + SetDataBank; {set data bank} + CnOut(m_plx); {get RTL address & original data bank} + CnOut(m_ply); + CnOut(m_lda_s); CnOut(3); {move CDev parameters} + CnOut(m_pha); + CnOut(m_lda_s); CnOut(3); + CnOut(m_pha); + CnOut(m_lda_s); CnOut(9); + CnOut(m_sta_s); CnOut(5); + CnOut(m_lda_s); CnOut(11); + CnOut(m_sta_s); CnOut(7); + CnOut(m_lda_s); CnOut(13); + CnOut(m_sta_s); CnOut(9); + CnOut(m_sta_s); CnOut(15); {store message in result space} + CnOut(m_lda_long); {store original user ID in result space} + RefName(@'~USER_ID',0,3,0); + CnOut(m_sta_s); CnOut(17); + CnOut(m_txa); {save RTL address & original data bank} + CnOut(m_sta_s); CnOut(11); + CnOut(m_tya); + CnOut(m_sta_s); CnOut(13); + CnOut(m_pea); CnOut2(1); {get user ID} CnOut(m_jsl); RefName(@'~DAID', 0, 3, 0); - CnOut(m_phb); - SetDataBank; - CnOut(m_pla); - CnOut(m_sta_s); CnOut(13); - CnOut(m_pla); - CnOut(m_sta_s); CnOut(13); - CnOut(m_jsl); + CnOut(m_jsl); {call CDev main routine} RefName(openName,0,3,0); - CnOut(m_tay); - CnOut(m_lda_s); CnOut(3); - CnOut(m_pha); - CnOut(m_lda_s); CnOut(3); - CnOut(m_pha); - CnOut(m_txa); - CnOut(m_sta_s); CnOut(7); - CnOut(m_tya); - CnOut(m_sta_s); CnOut(5); - CnOut(m_plb); - CnOut(m_rtl); + CnOut(m_jml); {clean up and return to caller} + RefName(@'~CDEVCLEANUP', 0, 3, 0); end {NBA initialization} diff --git a/cc.notes b/cc.notes index 6782303..e930e80 100644 --- a/cc.notes +++ b/cc.notes @@ -2057,6 +2057,8 @@ int foo(int[42]); 228. If a segment directive specifying a dynamic segment was used before the first function in the main source file, an invalid .root file would be generated, causing the resulting program to crash. (Note that having your program's main function in a dynamic segment serves little purpose and will cause an unrecoverable error if there is not enough free memory to load it. Also, CDevs, XCMDs, and NBAs cannot use dynamic segments.) +229. Each time a CDev written with ORCA/C was opened and closed, it would leak a user ID. If it was opened and closed many times, the system could run out of user IDs of the appropriate type, potentially causing problems. To avoid this, new cleanup code has been added that runs when a CDev is closed. To ensure this code gets run, CDevs written with ORCA/C should always set the wantClose flag so that they receive CloseCDEV messages, even if they do not otherwise need them. + -- Bugs from C 2.1.0 that have been fixed ----------------------------------- 1. In some situations, fread() reread the first 1K or so of the file.