Skip to content

Commit 0058763

Browse files
committed
A little mor for #396
Change ERROR into DAVERROR, because Windows has ERROR in assert.h...
1 parent 2ae427e commit 0058763

16 files changed

+1095
-208
lines changed

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,7 @@ SET(LIBHTTPD_SOURCES
734734
server/ssl.c
735735
server/scoreboard.c
736736
server/util.c
737+
server/util_atomics.c
737738
server/util_cfgtree.c
738739
server/util_cookies.c
739740
server/util_debug.c

NWGNUmakefile

+1
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ FILES_nlm_objs = \
268268
$(OBJDIR)/request.o \
269269
$(OBJDIR)/scoreboard.o \
270270
$(OBJDIR)/util.o \
271+
$(OBJDIR)/util_atomics.o \
271272
$(OBJDIR)/util_cfgtree.o \
272273
$(OBJDIR)/util_charset.o \
273274
$(OBJDIR)/util_cookies.o \

build/nw_export.inc

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "httpd.h"
3535

3636
/* Preprocess all of the standard HTTPD headers. */
37+
#include "ap_atomics.h"
3738
#include "ap_compat.h"
3839
#include "ap_listen.h"
3940
#include "ap_mmn.h"

include/ap_atomics.h

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
#include "ap_config.h"
2+
3+
#include "apr.h"
4+
5+
6+
/* Atomics for int (uses int32_t's on all platforms we care about) */
7+
8+
AP_DECLARE(int) ap_atomic_int_get(int volatile *val);
9+
10+
AP_DECLARE(void) ap_atomic_int_set(int volatile *val, int to);
11+
12+
AP_DECLARE(int) ap_atomic_int_xchg(int volatile *val, int with);
13+
14+
AP_DECLARE(int) ap_atomic_int_cas(int volatile *val, int with, int cmp);
15+
16+
AP_DECLARE(int) ap_atomic_int_add(int volatile *val, int add);
17+
18+
AP_DECLARE(int) ap_atomic_int_add_sat(int volatile *val, int add);
19+
20+
AP_DECLARE(int) ap_atomic_int_sub(int volatile *val, int sub);
21+
22+
AP_DECLARE(int) ap_atomic_int_sub_sat(int volatile *val, int sub);
23+
24+
25+
/* Atomics for unsigned int (uses uint32_t's on all platforms we care about) */
26+
27+
AP_DECLARE(unsigned int) ap_atomic_uint_get(unsigned int volatile *val);
28+
29+
AP_DECLARE(void) ap_atomic_uint_set(unsigned int volatile *val,
30+
unsigned int to);
31+
32+
AP_DECLARE(unsigned int) ap_atomic_uint_xchg(unsigned int volatile *val,
33+
unsigned int with);
34+
35+
AP_DECLARE(unsigned int) ap_atomic_uint_cas(unsigned int volatile *val,
36+
unsigned int with,
37+
unsigned int cmp);
38+
39+
AP_DECLARE(unsigned int) ap_atomic_uint_add(unsigned int volatile *val,
40+
unsigned int add);
41+
42+
AP_DECLARE(unsigned int) ap_atomic_uint_add_sat(unsigned int volatile *val,
43+
unsigned int add);
44+
45+
AP_DECLARE(unsigned int) ap_atomic_uint_sub(unsigned int volatile *val,
46+
unsigned int sub);
47+
48+
AP_DECLARE(unsigned int) ap_atomic_uint_sub_sat(unsigned int volatile *val,
49+
unsigned int sub);
50+
51+
52+
/* Atomics for long (uses int32_t's or int64_t's depending on LONG_MAX) */
53+
54+
AP_DECLARE(long) ap_atomic_long_get(long volatile *val);
55+
56+
AP_DECLARE(void) ap_atomic_long_set(long volatile *val, long to);
57+
58+
AP_DECLARE(long) ap_atomic_long_xchg(long volatile *val, long with);
59+
60+
AP_DECLARE(long) ap_atomic_long_cas(long volatile *val, long with, long cmp);
61+
62+
AP_DECLARE(long) ap_atomic_long_add(long volatile *val, long add);
63+
64+
AP_DECLARE(long) ap_atomic_long_add_sat(long volatile *val, long add);
65+
66+
AP_DECLARE(long) ap_atomic_long_sub(long volatile *val, long sub);
67+
68+
AP_DECLARE(long) ap_atomic_long_sub_sat(long volatile *val, long sub);
69+
70+
71+
/* Atomics for unsigned long (uses uint32_t's or uint64_t's depending on ULONG_MAX) */
72+
73+
AP_DECLARE(unsigned long) ap_atomic_ulong_get(unsigned long volatile *val);
74+
75+
AP_DECLARE(void) ap_atomic_ulong_set(unsigned long volatile *val,
76+
unsigned long to);
77+
78+
AP_DECLARE(unsigned long) ap_atomic_ulong_xchg(unsigned long volatile *val,
79+
unsigned long with);
80+
81+
AP_DECLARE(unsigned long) ap_atomic_ulong_cas(unsigned long volatile *val,
82+
unsigned long with,
83+
unsigned long cmp);
84+
85+
AP_DECLARE(unsigned long) ap_atomic_ulong_add(unsigned long volatile *val,
86+
unsigned long add);
87+
88+
AP_DECLARE(unsigned long) ap_atomic_ulong_add_sat(unsigned long volatile *val,
89+
unsigned long add);
90+
91+
AP_DECLARE(unsigned long) ap_atomic_ulong_sub(unsigned long volatile *val,
92+
unsigned long sub);
93+
94+
AP_DECLARE(unsigned long) ap_atomic_ulong_sub_sat(unsigned long volatile *val,
95+
unsigned long sub);
96+
97+
98+
/* Atomics for size_t (uses uint32_t's or uint64_t's depending on sizeof(void*)) */
99+
100+
AP_DECLARE(apr_size_t) ap_atomic_size_get(apr_size_t volatile *val);
101+
102+
AP_DECLARE(void) ap_atomic_size_set(apr_size_t volatile *val,
103+
apr_size_t to);
104+
105+
AP_DECLARE(apr_size_t) ap_atomic_size_xchg(apr_size_t volatile *val,
106+
apr_size_t with);
107+
108+
AP_DECLARE(apr_size_t) ap_atomic_size_cas(apr_size_t volatile *val,
109+
apr_size_t with,
110+
apr_size_t cmp);
111+
112+
AP_DECLARE(apr_size_t) ap_atomic_size_add(apr_size_t volatile *val,
113+
apr_size_t add);
114+
115+
AP_DECLARE(apr_size_t) ap_atomic_size_add_sat(apr_size_t volatile *val,
116+
apr_size_t add);
117+
118+
AP_DECLARE(apr_size_t) ap_atomic_size_sub(apr_size_t volatile *val,
119+
apr_size_t sub);
120+
121+
AP_DECLARE(apr_size_t) ap_atomic_size_sub_sat(apr_size_t volatile *val,
122+
apr_size_t sub);

include/ap_config.h

+18
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,19 @@
222222
#define AP_HAVE_DESIGNATED_INITIALIZER
223223
#endif
224224

225+
#ifndef __has_builtin /* check for supported builtin on clang */
226+
#define __has_builtin(x) 0
227+
#endif
228+
#ifndef __has_feature /* check for supported feature on clang */
229+
#define __has_feature(x) 0
230+
#endif
231+
#ifndef __has_extension /* check for supported extension on clang */
232+
#define __has_extension __has_feature
233+
#endif
225234
#ifndef __has_attribute /* check for supported attributes on clang */
226235
#define __has_attribute(x) 0
227236
#endif
237+
228238
#if (defined(__GNUC__) && __GNUC__ >= 4) || __has_attribute(sentinel)
229239
#define AP_FN_ATTR_SENTINEL __attribute__((sentinel))
230240
#else
@@ -261,5 +271,13 @@
261271
#define AP_FN_ATTR_NONNULL(x)
262272
#endif
263273

274+
/** Try harder to inline */
275+
#if __has_attribute(always_inline)
276+
#define AP_FORCE_INLINE APR_INLINE __attribute__((always_inline))
277+
#elif defined(_MSC_VER)
278+
#define AP_FORCE_INLINE APR_INLINE __forceinline
279+
#else
280+
#define AP_FORCE_INLINE APR_INLINE
281+
#endif
264282

265283
#endif /* AP_CONFIG_H */

include/httpd.h

+55
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@
6565
#if APR_HAVE_STDLIB_H
6666
#include <stdlib.h>
6767
#endif
68+
#if defined(__STDC__) || defined(_MSC_VER) /* C89 */
69+
#include <assert.h> /* for static_assert */
70+
#endif
6871

6972
/* Note: apr_uri.h is also included, see below */
7073

@@ -2423,6 +2426,58 @@ AP_DECLARE(void) ap_log_assert(const char *szExp, const char *szFile, int nLine)
24232426
#define AP_DEBUG_ASSERT(exp) ((void)0)
24242427
#endif
24252428

2429+
/**
2430+
* Compile time assertion with custom error message.
2431+
* @param exp static expression/condition
2432+
* @param msg error message (string literal)
2433+
*/
2434+
#if (defined(static_assert) \
2435+
|| (defined(__cplusplus) && __cplusplus >= 201103L) \
2436+
|| (defined(__has_feature) && __has_feature(cxx_static_assert)) \
2437+
|| (defined(_MSC_VER ) && _MSC_VER >= 1600))
2438+
2439+
#define AP_STATIC_ASSERT(exp, msg) static_assert(exp, msg)
2440+
2441+
#elif (defined(_Static_assert) \
2442+
|| (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) \
2443+
|| (defined(__has_feature) && __has_feature(c_static_assert)) \
2444+
|| (defined(__GNUC__) && __GNUC_PREREQ (4, 6)))
2445+
2446+
#define AP_STATIC_ASSERT(exp, msg) _Static_assert(exp, msg)
2447+
2448+
#else /* Fail compilation using bit-field with negative width */
2449+
2450+
#ifdef __COUNTER__
2451+
2452+
#define AP_STATIC_ASSERT(exp, msg) \
2453+
typedef __attribute__((unused)) struct { \
2454+
int static_assertion_failed: !!(exp) * 2 - 1; \
2455+
} AP_CONCATIFY(ap__static_assert_t_, __COUNTER__)
2456+
2457+
#else /* __COUNTER__ */
2458+
2459+
#define AP_STATIC_ASSERT(exp, msg) \
2460+
typedef __attribute__((unused)) struct { \
2461+
int static_assertion_failed: !!(exp) * 2 - 1; \
2462+
} AP_CONCATIFY(ap__static_assert_t_, __LINE__)
2463+
2464+
#endif /* __COUNTER__ */
2465+
2466+
#endif /* AP_STATIC_ASSERT */
2467+
2468+
/**
2469+
* Compile time assertion with the expression as error message.
2470+
* @param exp static expression/condition
2471+
*/
2472+
#define AP_BUILD_ASSERT(exp) \
2473+
AP_STATIC_ASSERT(exp, "static assertion failed at " \
2474+
__FILE__ ":" APR_STRINGIFY(__LINE__) ": " \
2475+
APR_STRINGIFY(exp))
2476+
2477+
/** Properly concatenate two values in the C preprocessor */
2478+
#define AP_CONCATIFY(x, y) AP__CONCATIFY(x, y)
2479+
#define AP__CONCATIFY(x, y) x ## y
2480+
24262481
/**
24272482
* @defgroup stopsignal Flags which indicate places where the server should stop for debugging.
24282483
* @{

libhttpd.dsp

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

modules/dav/main/ms_wdv.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ static dav_error *mswdv_combined_lock(request_rec *r)
182182
/* action */
183183
const char *failmsg = NULL;
184184
int http_error = HTTP_BAD_REQUEST;
185-
enum { ERROR, LOCK, UNLOCK, REFRESH, PASS } action = ERROR;
185+
enum { DAVERROR, LOCK, UNLOCK, REFRESH, PASS } action = DAVERROR;
186186

187187
lock_token_hdr = apr_table_get(r->headers_in, "Lock-Token");
188188
lock_timeout_hdr = apr_table_get(r->headers_in, "X-MSDAVEXTLockTimeout");
@@ -413,7 +413,7 @@ static dav_error *mswdv_combined_lock(request_rec *r)
413413
action == LOCK ? "LOCK" : "",
414414
action == UNLOCK ? "UNLOCK" : "",
415415
action == REFRESH ? "REFRESH" : "",
416-
action == ERROR ? "ERROR" : "",
416+
action == DAVERROR ? "ERROR" : "",
417417
action == PASS ? "PASS" : "");
418418

419419
if (failmsg) {
@@ -471,7 +471,7 @@ static dav_error *mswdv_combined_lock(request_rec *r)
471471
break;
472472
}
473473

474-
case ERROR: /* FALLTHROUGH */
474+
case DAVERROR: /* FALLTHROUGH */
475475
default:
476476
/* NOTREACHED */
477477
err = dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, 0,

modules/proxy/balancers/mod_lbmethod_bybusyness.c

+28-20
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "scoreboard.h"
2020
#include "ap_mpm.h"
2121
#include "apr_version.h"
22+
#include "ap_atomics.h"
2223
#include "ap_hooks.h"
2324

2425
module AP_MODULE_DECLARE_DATA lbmethod_bybusyness_module;
@@ -30,23 +31,30 @@ static APR_OPTIONAL_FN_TYPE(proxy_balancer_get_best_worker)
3031
static int is_best_bybusyness(proxy_worker *current, proxy_worker *prev_best, void *baton)
3132
{
3233
int *total_factor = (int *)baton;
33-
apr_size_t current_busy = ap_proxy_get_busy_count(current);
34-
apr_size_t prev_best_busy = 0;
35-
36-
current->s->lbstatus += current->s->lbfactor;
37-
*total_factor += current->s->lbfactor;
38-
if (prev_best)
39-
prev_best_busy = ap_proxy_get_busy_count(prev_best);
40-
41-
42-
return (
43-
!prev_best
44-
|| (current_busy < prev_best_busy)
45-
|| (
46-
(current_busy == prev_best_busy)
47-
&& (current->s->lbstatus > prev_best->s->lbstatus)
48-
)
49-
);
34+
int lbfactor = current->s->lbfactor, lbstatus;
35+
36+
*total_factor += lbfactor;
37+
lbstatus = ap_atomic_int_add_sat(&current->s->lbstatus, lbfactor);
38+
if (prev_best) {
39+
apr_size_t current_busy = ap_atomic_size_get(&current->s->busy);
40+
apr_size_t prev_busy = ap_atomic_size_get(&prev_best->s->busy);
41+
if (current_busy > prev_busy) {
42+
return 0;
43+
}
44+
if (current_busy == prev_busy) {
45+
/* lbstatus is the value before atomic add */
46+
if (lbstatus < APR_INT32_MAX - lbfactor) {
47+
lbstatus += lbfactor;
48+
}
49+
else {
50+
lbstatus = APR_INT32_MAX;
51+
}
52+
if (lbstatus <= ap_atomic_int_get(&prev_best->s->lbstatus)) {
53+
return 0;
54+
}
55+
}
56+
}
57+
return 1;
5058
}
5159

5260
static proxy_worker *find_best_bybusyness(proxy_balancer *balancer,
@@ -58,7 +66,7 @@ static proxy_worker *find_best_bybusyness(proxy_balancer *balancer,
5866
&total_factor);
5967

6068
if (worker) {
61-
worker->s->lbstatus -= total_factor;
69+
ap_atomic_int_sub_sat(&worker->s->lbstatus, total_factor);
6270
}
6371

6472
return worker;
@@ -71,8 +79,8 @@ static apr_status_t reset(proxy_balancer *balancer, server_rec *s)
7179
proxy_worker **worker;
7280
worker = (proxy_worker **)balancer->workers->elts;
7381
for (i = 0; i < balancer->workers->nelts; i++, worker++) {
74-
(*worker)->s->lbstatus = 0;
75-
ap_proxy_set_busy_count(*worker, 0);
82+
ap_atomic_int_set(&(*worker)->s->lbstatus, 0);
83+
ap_atomic_size_set(&(*worker)->s->busy, 0);
7684
}
7785
return APR_SUCCESS;
7886
}

0 commit comments

Comments
 (0)