This is Unofficial EPICS BASE Doxygen Site
osdThreadHooks.c
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2012 ITER Organization
3 * Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne
4 * National Laboratory.
5 *
6 * EPICS BASE is distributed subject to a Software License Agreement found
7 * in file LICENSE that is included with this distribution.
8 \*************************************************************************/
9 
10 /* Authors: Ralph Lange & Andrew Johnson */
11 
12 /* Secure hooks for epicsThread */
13 
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <errno.h>
17 #include <string.h>
18 
19 #include "ellLib.h"
20 #include "epicsMutex.h"
21 #include "epicsThread.h"
22 
25 
26 typedef struct epicsThreadHook {
30 
31 static ELLLIST hookList = ELLLIST_INIT;
32 static epicsMutexId hookLock;
33 
34 
35 static void threadHookOnce(void *arg)
36 {
37  hookLock = epicsMutexMustCreate();
38 
40  static epicsThreadHook defHook = {ELLNODE_INIT, NULL};
41 
42  defHook.func = epicsThreadHookDefault;
43  ellAdd(&hookList, &defHook.node);
44  }
45 }
46 
47 static void threadHookInit(void)
48 {
50 
51  epicsThreadOnce(&flag, threadHookOnce, NULL);
52 }
53 
55 {
56  epicsThreadHook *pHook;
57 
58  if (!hook) return 0;
59  threadHookInit();
60 
61  pHook = calloc(1, sizeof(epicsThreadHook));
62  if (!pHook) {
63  fprintf(stderr, "epicsThreadHookAdd: calloc failed\n");
64  return -1;
65  }
66  pHook->func = hook;
67 
68  if (epicsMutexLock(hookLock) == epicsMutexLockOK) {
69  ellAdd(&hookList, &pHook->node);
70  epicsMutexUnlock(hookLock);
71  return 0;
72  }
73  fprintf(stderr, "epicsThreadHookAdd: Locking problem\n");
74  return -1;
75 }
76 
78 {
79  if (!hook) return 0;
80  threadHookInit();
81 
82  if (epicsMutexLock(hookLock) == epicsMutexLockOK) {
83  epicsThreadHook *pHook = (epicsThreadHook *) ellFirst(&hookList);
84 
85  while (pHook) {
86  if (hook == pHook->func) {
87  ellDelete(&hookList, &pHook->node);
88  break;
89  }
90  pHook = (epicsThreadHook *) ellNext(&pHook->node);
91  }
92  epicsMutexUnlock(hookLock);
93  return 0;
94  }
95  fprintf(stderr, "epicsThreadHookAdd: Locking problem\n");
96  return -1;
97 }
98 
100 {
103 }
104 
105 LIBCOM_API void osdThreadHooksRun(epicsThreadId id)
106 {
107  threadHookInit();
108 
109  if (epicsMutexLock(hookLock) == epicsMutexLockOK) {
110  epicsThreadHook *pHook = (epicsThreadHook *) ellFirst(&hookList);
111 
112  while (pHook) {
113  pHook->func(id);
114  pHook = (epicsThreadHook *) ellNext(&pHook->node);
115  }
116  epicsMutexUnlock(hookLock);
117  }
118  else {
119  fprintf(stderr, "osdThreadHooksRun: Locking problem\n");
120  }
121 }
122 
123 LIBCOM_API void epicsThreadHooksShow(void)
124 {
125  threadHookInit();
126 
127  if (epicsMutexLock(hookLock) == epicsMutexLockOK) {
128  epicsThreadHook *pHook = (epicsThreadHook *) ellFirst(&hookList);
129 
130  while (pHook) {
131  printf(" %p\n", pHook->func);
132  pHook = (epicsThreadHook *) ellNext(&pHook->node);
133  }
134  epicsMutexUnlock(hookLock);
135  }
136  else {
137  fprintf(stderr, "epicsThreadHooksShow: Locking problem\n");
138  }
139 }
LIBCOM_API int epicsThreadHookDelete(EPICS_THREAD_HOOK_ROUTINE hook)
LIBCOM_API EPICS_THREAD_HOOK_ROUTINE epicsThreadHookMain
struct epicsThreadHook epicsThreadHook
LIBCOM_API int epicsThreadHookAdd(EPICS_THREAD_HOOK_ROUTINE hook)
void(* EPICS_THREAD_HOOK_ROUTINE)(epicsThreadId id)
Definition: epicsThread.h:302
#define printf
Definition: epicsStdio.h:41
#define epicsMutexMustCreate()
Create an epicsMutex semaphore for use from C code.
Definition: epicsMutex.h:179
#define NULL
Definition: catime.c:38
#define ELLLIST_INIT
Value of an empty list.
Definition: ellLib.h:63
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
Definition: epicsMutex.cpp:140
LIBCOM_API void osdThreadHooksRunMain(epicsThreadId id)
LIBCOM_API EPICS_THREAD_HOOK_ROUTINE epicsThreadHookDefault
A doubly-linked list library.
void ellAdd(ELLLIST *pList, ELLNODE *pNode)
Adds a node to the end of a list.
Definition: ellLib.c:24
#define ellNext(PNODE)
Find the next node in list.
Definition: ellLib.h:99
#define EPICS_THREAD_ONCE_INIT
Definition: epicsThread.h:109
APIs for the epicsMutex mutual exclusion semaphore.
LIBCOM_API void epicsStdCall epicsThreadOnce(epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg)
LIBCOM_API void epicsThreadHooksShow(void)
List node type.
Definition: ellLib.h:45
epicsMutexLockStatus epicsStdCall epicsMutexLock(epicsMutexId pmutexNode)
Claim the semaphore, waiting until it&#39;s free if currently owned owned by a different thread...
Definition: epicsMutex.cpp:145
#define stderr
Definition: epicsStdio.h:32
EPICS_THREAD_HOOK_ROUTINE func
List header type.
Definition: ellLib.h:56
C++ and C descriptions for a thread.
LIBCOM_API void osdThreadHooksRun(epicsThreadId id)
void ellDelete(ELLLIST *pList, ELLNODE *pNode)
Deletes a node from a list.
Definition: ellLib.c:75
#define ELLNODE_INIT
Value of a terminal node.
Definition: ellLib.h:52
#define ellFirst(PLIST)
Find the first node in list.
Definition: ellLib.h:89