From 138a4686907e588b9382a545f0124bf4e2429266 Mon Sep 17 00:00:00 2001 From: mwinkel-dev <122583770+mwinkel-dev@users.noreply.github.com> Date: Mon, 9 Oct 2023 10:28:50 -0600 Subject: [PATCH] Fix: 2625 v4 -- IDL socket 0 issue and partial revert of PR #2620 (#2635) * Fix: 2625 - IDL only by replace keyword_set() * Fix: 2625 - Integrity check when add connection * Fix: 2625 v4 - update debian packaging for IDL * Fix: 2625 - correct typo in comment * Fix: 2625 v4 - mdsdisconnect now correctly passes connection ID to the C library, mdsipshr * Fix: 2625 v4 - more explanation of why mds_keyword_set() is needed * Fix: 2625 v4 - revert PR 2620 connection.py change * Fix: 2625 v4 -- add new IDL file to package for RHEL / Rocky --------- Co-authored-by: Mark Winkel --- deploy/packaging/debian/idl.noarch | 1 + deploy/packaging/redhat/idl.noarch | 1 + idl/mds_keyword_set.pro | 10 ++++++++++ idl/mdsconnect.pro | 8 +++++--- idl/mdsdisconnect.pro | 8 +++++--- idl/mdsisclient.pro | 17 ++++++++++++----- mdstcpip/mdsipshr/Connections.c | 2 +- python/MDSplus/connection.py | 6 +----- 8 files changed, 36 insertions(+), 17 deletions(-) create mode 100755 idl/mds_keyword_set.pro diff --git a/deploy/packaging/debian/idl.noarch b/deploy/packaging/debian/idl.noarch index dc4f05c6b0..b23bd0ca37 100644 --- a/deploy/packaging/debian/idl.noarch +++ b/deploy/packaging/debian/idl.noarch @@ -36,6 +36,7 @@ ./usr/local/mdsplus/idl/mdsevent.pro ./usr/local/mdsplus/idl/mdsgetmsg.pro ./usr/local/mdsplus/idl/mdsidlimage.pro +./usr/local/mdsplus/idl/mds_keyword_set.pro ./usr/local/mdsplus/idl/mdsisclient.pro ./usr/local/mdsplus/idl/mdslogin.pro ./usr/local/mdsplus/idl/mdsopen.pro diff --git a/deploy/packaging/redhat/idl.noarch b/deploy/packaging/redhat/idl.noarch index 032c74eb0c..9d983c07fa 100644 --- a/deploy/packaging/redhat/idl.noarch +++ b/deploy/packaging/redhat/idl.noarch @@ -40,6 +40,7 @@ ./usr/local/mdsplus/idl/mdsgetmsg.pro ./usr/local/mdsplus/idl/mdsidlimage.pro ./usr/local/mdsplus/idl/mdsisclient.pro +./usr/local/mdsplus/idl/mds_keyword_set.pro ./usr/local/mdsplus/idl/mdslogin.pro ./usr/local/mdsplus/idl/mdsopen.pro ./usr/local/mdsplus/idl/mdsput.pro diff --git a/idl/mds_keyword_set.pro b/idl/mds_keyword_set.pro new file mode 100755 index 0000000000..9b891cda4f --- /dev/null +++ b/idl/mds_keyword_set.pro @@ -0,0 +1,10 @@ +; This function detects if an optional keyword is present, regardless of value. +; IDL's keyword_set() only detects non-zero optional keywords (see Issue 2625). +; So replace it with this function that also handles zero. +function mds_keyword_set,socket=socket + if (n_elements(socket) gt 0) then begin + return, 1 + endif else begin + return, 0 + endelse +end diff --git a/idl/mdsconnect.pro b/idl/mdsconnect.pro index 77e5fea488..1824bf7289 100644 --- a/idl/mdsconnect.pro +++ b/idl/mdsconnect.pro @@ -10,10 +10,11 @@ function sockmin end function mds$socket,quiet=quiet,status=status,socket=socket + forward_function mds_keyword_set status = 1 sockmin=sockmin() sock=sockmin-1 - if (keyword_set(socket)) then $ + if (mds_keyword_set(socket=socket)) then $ if (socket ge sockmin) then $ return, socket defsysv,'!MDS_SOCKET',exists=old_sock @@ -152,8 +153,9 @@ end pro mdsconnect,host,status=status,quiet=quiet,port=port,socket=socket + forward_function mds_keyword_set on_error,2 - if (not keyword_set(socket)) then $ + if (not mds_keyword_set(socket=socket)) then $ mdsdisconnect,/quiet if n_elements(port) ne 0 then begin setenv_,'mdsip='+strtrim(port,2) @@ -165,7 +167,7 @@ pro mdsconnect,host,status=status,quiet=quiet,port=port,socket=socket sockmin=sockmin() if (sock ge sockmin) then begin status = 1 - if not keyword_set(socket) then $ + if not mds_keyword_set(socket=socket) then $ !MDS_SOCKET = sock $ else $ socket = sock diff --git a/idl/mdsdisconnect.pro b/idl/mdsdisconnect.pro index f91140f1a2..2cc70f0b89 100644 --- a/idl/mdsdisconnect.pro +++ b/idl/mdsdisconnect.pro @@ -1,15 +1,17 @@ pro mdsdisconnect,status=status,quiet=quiet, socket=socket + forward_function mds_keyword_set forward_function mds$socket, MdsIPImage image = MdsIPImage() status = 1 - if keyword_set(socket) then $ + if mds_keyword_set(socket=socket) then $ sock = socket $ else $ sock = mds$socket(status=status,quiet=quiet) if status then begin - status = call_external(image,'DisconnectFromMds',sock,value=[1b]) + ; IDL's AUTO_GLUE feature requires a C / C++ compiler on the system + status = call_external(image,'DisconnectFromMds',sock,value=[1b], /AUTO_GLUE) if (status eq 0) then status = 1 else status = 0 - if not keyword_set(socket) then $ + if not mds_keyword_set(socket=socket) then $ !MDS_SOCKET = -1l endif return diff --git a/idl/mdsisclient.pro b/idl/mdsisclient.pro index 198d2a303d..87c420296a 100644 --- a/idl/mdsisclient.pro +++ b/idl/mdsisclient.pro @@ -1,13 +1,20 @@ function mdsisclient,socket=socket -if (keyword_set(socket)) then $ - if (socket ge 0) then $ - return, 1 $ - else $ - return, 0 + forward_function mds_keyword_set + + ; If optional socket provided, use it + if (mds_keyword_set(socket=socket)) then $ + if (socket ge 0) then $ + return, 1 $ + else $ + return, 0 + + ; Otherwise use the last socket defsysv,'!MDS_SOCKET',exists=mdsClient if (mdsClient) then begin value= (!MDS_SOCKET ge 0) return,value + + ; Went awry, so return INVALID_CONNECTION_ID endif else begin defsysv,'!MDS_SOCKET',-1 return,0 diff --git a/mdstcpip/mdsipshr/Connections.c b/mdstcpip/mdsipshr/Connections.c index 297614d235..c9b0ec6c46 100644 --- a/mdstcpip/mdsipshr/Connections.c +++ b/mdstcpip/mdsipshr/Connections.c @@ -471,7 +471,7 @@ int AddConnection(Connection *c) do { id++; // find next free id - } while (id == INVALID_CONNECTION_ID && _FindConnection(id, NULL, MDSIPTHREADSTATIC_VAR)); + } while ((id == INVALID_CONNECTION_ID) || _FindConnection(id, NULL, MDSIPTHREADSTATIC_VAR)); c->id = id; pthread_mutex_unlock(&lock); c->state |= CON_INLIST; diff --git a/python/MDSplus/connection.py b/python/MDSplus/connection.py index 4e4c367bc1..8599ccf9cd 100644 --- a/python/MDSplus/connection.py +++ b/python/MDSplus/connection.py @@ -205,16 +205,12 @@ def get(self, exp, *args, **kwargs): args = kwargs['arglist'] timeout = kwargs.get('timeout', -1) num = len(args)+1 - - exp = 'serializeout(`('+exp+'))' - exp = _ver.tobytes(exp) _exc.checkStatus(_SendArg(self.conid, 0, 14, num, len(exp), 0, 0, ctypes.c_char_p(exp))) for i, arg in enumerate(args): self._send_arg(arg, i+1, num) - retSerialized = self._get_answer(timeout) - return retSerialized.deserialize() + return self._get_answer(timeout) class Connection(object):