13
13
#include "tools.h"
14
14
15
15
#define RESPAWN_FILE "/etc/ueld/respawn.list"
16
- #define MAX_APP 32
16
+ #define HASHTABLE_FIRST_NODE_SIZE 32
17
17
18
- struct respawn_app {
18
+ struct respawn_node {
19
+ int nref ;
19
20
int vt ;
20
21
pid_t pid ;
21
- char * cmd ;
22
+ char * cmd ;
23
+ struct respawn_node * next ;
22
24
};
23
25
24
- static struct respawn_app apps [ MAX_APP ];
25
- static unsigned int appssz = 0 ;
26
+ static struct respawn_node * first_nodes [ HASHTABLE_FIRST_NODE_SIZE ];
27
+ static unsigned int disable = 0 ;
26
28
27
29
static size_t length ;
28
- static char * respawn ;
30
+ static char * respawn ;
29
31
30
- static void runapp (struct respawn_app * app )
32
+ #define hashpid (pid ) ((pid) % HASHTABLE_FIRST_NODE_SIZE)
33
+ #define nodefree (node ) (free(node))
34
+ #define noderef (node ) (((node)->nref)++)
35
+
36
+ #ifdef __GNUC__
37
+ #define likely (x ) __builtin_expect((x),1)
38
+ #define unlikely (x ) __builtin_expect((x),0)
39
+ #else
40
+ #define likely (x ) (x)
41
+ #define unlikely (x ) (x)
42
+ #endif /* __GNUC__ */
43
+
44
+ static struct respawn_node * nodenew ()
45
+ {
46
+ static struct respawn_node * node ;
47
+
48
+ if ((node = malloc (sizeof (struct respawn_node ))) == NULL ) {
49
+ return NULL ;
50
+ }
51
+
52
+ node -> nref = 1 ;
53
+ return node ;
54
+ }
55
+
56
+ static void nodeunref (struct respawn_node * node )
57
+ {
58
+ node -> nref = node -> nref - 1 ;
59
+ if (node -> nref <= 0 ) {
60
+ nodefree (node );
61
+ }
62
+ }
63
+
64
+ static void insert (pid_t key , struct respawn_node * node )
65
+ {
66
+ int index = hashpid (key );
67
+
68
+ noderef (node );
69
+ node -> next = NULL ;
70
+
71
+ if (first_nodes [index ] == NULL ) {
72
+ first_nodes [index ] = node ;
73
+ } else {
74
+ struct respawn_node * prenode = first_nodes [index ];
75
+ while (prenode -> next != NULL ) {
76
+ prenode = prenode -> next ;
77
+ }
78
+ prenode -> next = node ;
79
+ }
80
+ }
81
+
82
+ static struct respawn_node * get (pid_t key )
83
+ {
84
+ int index = hashpid (key );
85
+
86
+ struct respawn_node * node = first_nodes [index ];
87
+ while (node != NULL ) {
88
+ if (node -> pid == key ) {
89
+ return node ;
90
+ }
91
+
92
+ node = node -> next ;
93
+ }
94
+
95
+ return NULL ;
96
+ }
97
+
98
+ static void delete (pid_t key )
99
+ {
100
+ int index = hashpid (key );
101
+
102
+ struct respawn_node * prenode = NULL ;
103
+ struct respawn_node * node = first_nodes [index ];
104
+ while (node != NULL ) {
105
+ if (node -> pid == key ) {
106
+ if (prenode ) {
107
+ prenode -> next = node -> next ;
108
+ } else {
109
+ first_nodes [index ] = node -> next ;
110
+ }
111
+
112
+ nodeunref (node );
113
+ }
114
+
115
+ prenode = node ;
116
+ node = node -> next ;
117
+ }
118
+ }
119
+
120
+ static pid_t runapp (struct respawn_node * app )
31
121
{
32
122
pid_t pid ;
33
123
@@ -39,11 +129,14 @@ static void runapp(struct respawn_app* app)
39
129
40
130
if (pid < 0 ) pid = 0 ;
41
131
app -> pid = pid ;
132
+
133
+ return pid ;
42
134
}
43
135
44
136
void respawn_init ()
45
137
{
46
138
int fd ;
139
+ int appssz = 0 ;
47
140
char * p , * vt , * cmd ;
48
141
49
142
if ((fd = open (RESPAWN_FILE , O_RDONLY )) < 0 )
@@ -75,11 +168,25 @@ void respawn_init()
75
168
* p = 0 ;
76
169
p ++ ;
77
170
78
- apps [appssz ].vt = atoi (vt );
79
- apps [appssz ].pid = 0 ;
80
- apps [appssz ].cmd = cmd ;
171
+ struct respawn_node * node ;
172
+ if ((node = nodenew ()) != NULL ) {
173
+ node -> vt = atoi (vt );
174
+ node -> pid = 0 ;
175
+ node -> cmd = cmd ;
176
+
177
+ pid_t pid = runapp (node );
178
+
179
+ if (unlikely (pid <= 0 )) {
180
+ ueld_print ("Run respwan process '%s' first time failed\n" , cmd );
181
+ } else {
182
+ appssz ++ ;
183
+ insert (pid , node );
184
+ }
81
185
82
- runapp (& apps [appssz ++ ]);
186
+ nodeunref (node );
187
+ } else {
188
+ ueld_print ("Create respwan node for '%s' failed\n" , cmd );
189
+ }
83
190
}
84
191
85
192
if (!appssz )
@@ -88,25 +195,44 @@ void respawn_init()
88
195
89
196
void respawnpid (pid_t pid )
90
197
{
91
- for (int i = 0 ; i < appssz ; i ++ ) {
92
- if (apps [i ].pid == pid ) {
93
- runapp (& apps [i ]);
94
- break ;
198
+ if (disable ) {
199
+ return ;
200
+ }
201
+
202
+ struct respawn_node * node ;
203
+ if ((node = get (pid )) != NULL ) {
204
+ pid_t newpid = runapp (node );
205
+
206
+ if (unlikely (newpid <= 0 )) {
207
+ ueld_print ("Respwan process '%s' failed, remove it from list...\n" , node -> cmd );
208
+ delete (node -> pid );
209
+ } else {
210
+ noderef (node );
211
+ delete (node -> pid );
212
+ node -> pid = newpid ;
213
+ insert (newpid , node );
214
+ nodeunref (node );
95
215
}
96
216
}
97
217
}
98
218
99
219
void clearpid (pid_t pid )
100
220
{
101
- if (pid == 0 ) {
102
- munmap (respawn , length );
103
- appssz = 0 ;
104
- }
105
-
106
- for (int i = 0 ; i < appssz ; i ++ ) {
107
- if (apps [i ].pid == pid ) {
108
- apps [i ].pid = 0 ;
109
- break ;
221
+ if (pid != 0 ) {
222
+ delete (pid );
223
+ } else {
224
+ disable = 1 ;
225
+ for (int i = 0 ; i < HASHTABLE_FIRST_NODE_SIZE ; i ++ ) {
226
+ if (first_nodes [i ] != NULL ) {
227
+ struct respawn_node * node = first_nodes [i ];
228
+ while (node -> next != NULL ) {
229
+ struct respawn_node * tmp = node ;
230
+ node = node -> next ;
231
+ nodeunref (tmp );
232
+ }
233
+ nodeunref (node );
234
+ first_nodes [i ] = NULL ;
235
+ }
110
236
}
111
237
}
112
238
}
0 commit comments