root/src/modules/test_abort.c

Revision 1a778bd1b1b6f321eff6ff69403dd1cd55d8ef1a, 6.7 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 3 years ago)

this doesn't need libpq headers

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007-2010, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  *       notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  *       copyright notice, this list of conditions and the following
13  *       disclaimer in the documentation and/or other materials provided
14  *       with the distribution.
15  *     * Neither the name OmniTI Computer Consulting, Inc. nor the names
16  *       of its contributors may be used to endorse or promote products
17  *       derived from this software without specific prior written
18  *       permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include "noit_defines.h"
34
35 #include <stdio.h>
36 #include <unistd.h>
37 #include <errno.h>
38 #include <assert.h>
39 #include <math.h>
40
41 #include "noit_module.h"
42 #include "noit_check.h"
43 #include "noit_check_tools.h"
44 #include "utils/noit_log.h"
45 #include "utils/noit_hash.h"
46
47 #ifndef BOOLOID
48 #define BOOLOID                  16
49 #endif
50 #ifndef INT2OID
51 #define INT2OID                  21
52 #endif
53 #ifndef INT4OID
54 #define INT4OID                  23
55 #endif
56 #ifndef INT8OID
57 #define INT8OID                  20
58 #endif
59 #ifndef FLOAT4OID
60 #define FLOAT4OID                700
61 #endif
62 #ifndef FLOAT8OID
63 #define FLOAT8OID                701
64 #endif
65 #ifndef NUMERICOID
66 #define NUMERICOID               1700
67 #endif
68
69 typedef struct {
70   noit_module_t *self;
71   noit_check_t *check;
72   int rv;
73   int timed_out;
74   double timeout;
75   int method;
76   int ignore_signals;
77 } test_abort_check_info_t;
78
79 static noit_log_stream_t nlerr = NULL;
80 static noit_log_stream_t nldeb = NULL;
81
82 static void test_abort_cleanup(noit_module_t *self, noit_check_t *check) {
83   test_abort_check_info_t *ci = check->closure;
84   if(ci) {
85     memset(ci, 0, sizeof(*ci));
86   }
87 }
88
89 static int test_abort_drive_session(eventer_t e, int mask, void *closure,
90                                   struct timeval *passed_now) {
91   struct timespec rqtp;
92   struct timeval target_time, now, diff;
93   double i, r;
94   test_abort_check_info_t *ci = closure;
95   noit_check_t *check = ci->check;
96
97   if(mask & (EVENTER_READ | EVENTER_WRITE)) {
98     /* this case is impossible from the eventer.  It is called as
99      * such on the synchronous completion of the event.
100      */
101     stats_t current;
102     noit_check_stats_clear(&current);
103     current.available = NP_AVAILABLE;
104     current.state = ci->timed_out ? NP_BAD : NP_GOOD;
105     noitL(nlerr, "test_abort: EVENTER_READ | EVENTER_WRITE\n");
106     noit_check_set_stats(ci->self, check, &current);
107     check->flags &= ~NP_RUNNING;
108     return 0;
109   }
110   switch(mask) {
111     case EVENTER_ASYNCH_WORK:
112       noitL(nlerr, "test_abort: EVENTER_ASYNCH_WORK\n");
113       r = modf(ci->timeout, &i);
114       ci->timed_out = 1;
115      
116       if(ci->ignore_signals) { /* compuational loop */
117         double trash = 1.0;
118         gettimeofday(&now, NULL);
119         diff.tv_sec = (int)i;
120         diff.tv_usec = (int)(r * 1000000.0);
121         add_timeval(now, diff, &target_time);
122
123         do {
124           for(i=0; i<100000; i++) {
125             trash += drand48();
126             trash = log(trash);
127             trash += 1.1;
128             trash = exp(trash);
129           }
130           gettimeofday(&now, NULL);
131           sub_timeval(target_time, now, &diff);
132         } while(diff.tv_sec >= 0 && diff.tv_usec >= 0);
133       }
134       else {
135         rqtp.tv_sec = (int)i;
136         rqtp.tv_nsec = (int)(r * 1000000000.0);
137         nanosleep(&rqtp,NULL);
138       }
139       noitL(nlerr, "test_abort: EVENTER_ASYNCH_WORK (done)\n");
140       ci->timed_out = 0;
141       return 0;
142       break;
143     case EVENTER_ASYNCH_CLEANUP:
144       /* This sets us up for a completion call. */
145       noitL(nlerr, "test_abort: EVENTER_ASYNCH_CLEANUP\n");
146       e->mask = EVENTER_READ | EVENTER_WRITE;
147       break;
148     default:
149       abort();
150   }
151   return 0;
152 }
153
154 static int test_abort_initiate(noit_module_t *self, noit_check_t *check) {
155   test_abort_check_info_t *ci = check->closure;
156   struct timeval __now;
157   const char *v;
158
159   noitL(nlerr, "test_abort_initiate\n");
160   /* We cannot be running */
161   assert(!(check->flags & NP_RUNNING));
162   check->flags |= NP_RUNNING;
163
164   ci->self = self;
165   ci->check = check;
166   ci->timeout = 30;
167   if(noit_hash_retr_str(check->config, "sleep", strlen("sleep"), &v)) {
168     ci->timeout = atof(v);
169   }
170   ci->ignore_signals = 0;
171   if(noit_hash_retr_str(check->config, "ignore_signals", strlen("ignore_signals"), &v)) {
172     if(!strcmp(v, "true")) ci->ignore_signals = 1;
173   }
174   ci->timed_out = 1;
175
176   ci->method = 0;
177   if(noit_hash_retr_str(check->config, "method", strlen("method"), &v)) {
178     if(!strcmp(v, "evil")) ci->method = EVENTER_EVIL_BRUTAL;
179     else if(!strcmp(v, "deferred")) ci->method = EVENTER_CANCEL_DEFERRED;
180     else if(!strcmp(v, "asynch")) ci->method = EVENTER_CANCEL_ASYNCH;
181   }
182   memcpy(&check->last_fire_time, &__now, sizeof(__now));
183
184   /* Register a handler for the worker */
185   noit_check_run_full_asynch_opts(check, test_abort_drive_session, ci->method);
186   return 0;
187 }
188
189 static int test_abort_initiate_check(noit_module_t *self, noit_check_t *check,
190                                    int once, noit_check_t *parent) {
191   if(!check->closure) check->closure = calloc(1, sizeof(test_abort_check_info_t));
192   INITIATE_CHECK(test_abort_initiate, self, check);
193   return 0;
194 }
195
196 static int test_abort_onload(noit_image_t *self) {
197   nlerr = noit_log_stream_find("error/test_abort");
198   nldeb = noit_log_stream_find("debug/test_abort");
199   if(!nlerr) nlerr = noit_stderr;
200   if(!nldeb) nldeb = noit_debug;
201
202   eventer_name_callback("http/test_abort_drive_session", test_abort_drive_session);
203   return 0;
204 }
205
206 noit_module_t test_abort = {
207   {
208     NOIT_MODULE_MAGIC,
209     NOIT_MODULE_ABI_VERSION,
210     "test_abort",
211     "test_abort internal tool for eventer testing",
212     "",
213     test_abort_onload
214   },
215   NULL,
216   NULL,
217   test_abort_initiate_check,
218   test_abort_cleanup
219 };
220
Note: See TracBrowser for help on using the browser.