EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: Problem in errlogRemoveListener
From: Andrew Johnson <[email protected]>
To: [email protected]
Date: Fri, 21 Jun 2013 17:01:34 -0500
Lets try again *with* the patch file this time...

Hi Benjamin,

On 2013-06-21 Benjamin Franksen wrote:
> Cool. However, for 3.15 I propose to change the existing
>  errlogRemoveListener, instead of adding a new function; I was speculating
>  on the patch being accepted for 3.14.12.4, which is why I added a new
>  function.

I added the ability to delete multiple listeners, and it now returns a count 
of the number actually removed.

This version (against 3.15) renames the function and adds a flags argument, 
but provides an API-compatible macro for code written against 3.14, plus some 
others to give it a simple API.

Comments welcome.

- Andrew
-- 
Advertising may be described as the science of arresting the human
intelligence long enough to get money from it. -- Stephen Leacock
=== modified file 'src/libCom/error/errlog.c'
--- src/libCom/error/errlog.c	2012-11-09 23:06:32 +0000
+++ src/libCom/error/errlog.c	2013-06-21 21:16:52 +0000
@@ -331,11 +331,12 @@
     ellAdd(&pvtData.listenerList,&plistenerNode->node);
     epicsMutexUnlock(pvtData.listenerLock);
 }
-    
-epicsShareFunc void epicsShareAPI errlogRemoveListener(
-    errlogListener listener)
+
+epicsShareFunc int epicsShareAPI errlogDeleteListeners(
+    errlogListener listener, errlogDelFlags flags, void *pPrivate)
 {
     listenerNode *plistenerNode;
+    int count = 0;
 
     errlogInit(0);
     if (!pvtData.atExit)
@@ -343,21 +344,28 @@
 
     plistenerNode = (listenerNode *)ellFirst(&pvtData.listenerList);
     while (plistenerNode) {
-        if (plistenerNode->listener==listener) {
+        listenerNode *pnext = (listenerNode *)ellNext(&plistenerNode->node);
+
+        if (plistenerNode->listener == listener &&
+            ((flags & errlogDel_Generic) ||
+             plistenerNode->pPrivate == pPrivate)) {
             ellDelete(&pvtData.listenerList, &plistenerNode->node);
-            free((void *)plistenerNode);
-            break;
+            free(plistenerNode);
+            ++count;
+            if (flags & errlogDel_One)
+                break;
         }
-        plistenerNode = (listenerNode *)ellNext(&plistenerNode->node);
+        plistenerNode = pnext;
     }
 
     if (!pvtData.atExit)
         epicsMutexUnlock(pvtData.listenerLock);
 
-    if (!plistenerNode) {
+    if ((flags & errlogDel_One) && count == 0) {
         fprintf(pvtData.console,
             "errlogRemoveListener did not find listener\n");
     }
+    return count;
 }
 
 epicsShareFunc int epicsShareAPI eltc(int yesno)

=== modified file 'src/libCom/error/errlog.h'
--- src/libCom/error/errlog.h	2012-11-09 23:06:32 +0000
+++ src/libCom/error/errlog.h	2013-06-21 21:14:53 +0000
@@ -32,6 +32,19 @@
 
 typedef enum {errlogInfo, errlogMinor, errlogMajor, errlogFatal} errlogSevEnum;
 
+/* Flags for errlogDeleteListeners */
+typedef enum {
+    /* Define flag bits for internal use */
+    errlogDel_One = 1,      /* Remove only the first listener */
+    errlogDel_Generic = 2,  /* Ignore the pPrivate value */
+
+    /* These are the public flag values */
+    errlogDel_All_Specific = 0,
+    errlogDel_One_Specific = errlogDel_One,
+    errlogDel_All_Generic  = errlogDel_Generic,
+    errlogDel_One_Generic  = errlogDel_One | errlogDel_Generic
+} errlogDelFlags;
+
 #ifdef ERRLOG_INIT
 epicsShareDef char * errlogSevEnumString[] = {"info","minor","major","fatal"};
 #else
@@ -57,8 +70,16 @@
 
 epicsShareFunc void epicsShareAPI errlogAddListener(
     errlogListener listener, void *pPrivate);
-epicsShareFunc void epicsShareAPI errlogRemoveListener(
-    errlogListener listener);
+epicsShareFunc int epicsShareAPI errlogDeleteListeners(
+    errlogListener listener, errlogDelFlags flags, void *pPrivate);
+#define errlogRemoveListener(listener) \
+    errlogDeleteListeners(listener, errlogDel_One_Generic, 0)
+#define errlogRemoveListeners(listener) \
+    errlogDeleteListeners(listener, errlogDel_All_Generic, 0)
+#define errlogRemoveSpecificListener(listener, private) \
+    errlogDeleteListeners(listener, errlogDel_One_Specific, private)
+#define errlogRemoveSpecificListeners(listener, private) \
+    errlogDeleteListeners(listener, errlogDel_All_Specific, private)
 
 epicsShareFunc int epicsShareAPI eltc(int yesno);
 epicsShareFunc int errlogSetConsole(FILE *stream);

=== modified file 'src/libCom/test/epicsErrlogTest.c'
--- src/libCom/test/epicsErrlogTest.c	2011-11-14 23:42:50 +0000
+++ src/libCom/test/epicsErrlogTest.c	2013-06-21 20:59:10 +0000
@@ -142,7 +142,7 @@
     char msg[256];
     clientPvt pvt, pvt2;
 
-    testPlan(29);
+    testPlan(32);
 
     strcpy(msg, truncmsg);
 
@@ -187,7 +187,8 @@
     testOk1(pvt2.count == 1);
 
     /* Removes the first listener, but the second remains */
-    errlogRemoveListener(&logClient);
+    testOk(1 == errlogRemoveSpecificListener(&logClient, &pvt),
+        "Removed 1 listener");
 
     pvt2.expect = "Testing3";
     pvt2.checkLen = strlen(pvt2.expect);
@@ -198,8 +199,10 @@
     testOk1(pvt.count == 2);
     testOk1(pvt2.count == 2);
 
-    /* Remove the second listener */
-    errlogRemoveListener(&logClient);
+    /* Add the second listener again, then remove both instances */
+    errlogAddListener(&logClient, &pvt2);
+    testOk(2 == errlogRemoveSpecificListeners(&logClient, &pvt2),
+        "Removed 2 listeners");
 
     errlogPrintfNoConsole("Something different");
     errlogFlush();
@@ -314,7 +317,8 @@
     testOk1(pvt.count == N+1);
 
     /* Clean up */
-    errlogRemoveListener(&logClient);
+    testOk(1 == errlogRemoveListeners(&logClient),
+        "Removed 1 listener");
 
     testLogPrefix();
 


Replies:
Re: Problem in errlogRemoveListener Benjamin Franksen

Navigate by Date:
Prev: RE: Using all the cores available on modern processors Mark Rivers
Next: Re: VAL field of PV in ASYN driver Vishnu Patel
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: Problem in errlogRemoveListener Andrew Johnson
Next: Re: Problem in errlogRemoveListener Benjamin Franksen
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 20 Apr 2015 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·