You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
|
1
(2) |
2
|
3
|
|
4
|
5
|
6
|
7
(11) |
8
|
9
|
10
|
|
11
(2) |
12
|
13
|
14
|
15
|
16
|
17
|
|
18
(1) |
19
|
20
|
21
|
22
(1) |
23
|
24
|
|
25
|
26
|
27
|
28
(2) |
29
(3) |
30
(2) |
31
|
|
From: Dmitry A. <dma...@ya...> - 2020-10-01 09:47:13
|
On 10/1/20 6:36 AM, Bart Van Assche wrote:
> Please add a regression test that calls pthread_cond_clockwait() such
> that the code added by this patch is tested when running the regression
> tests.
OK.
> Additionally, please use git send-email when posting patches
> instead of sending these as an attachment. It is much easier to
> reply to an inline patch than to comment on an attachment.
Ugh, it seems that my goddamned ISP treats git-send-email as
an automated SPAM sender :-(. I'll try to fix it ASAP.
Dmitry
---
configure.ac | 1 +
drd/drd_pthread_intercepts.c | 26 +++++
helgrind/hg_intercepts.c | 105 ++++++++++++++++++
helgrind/tests/Makefile.am | 6 +
helgrind/tests/cond_clockwait_invalid.c | 35 ++++++
.../tests/cond_clockwait_invalid.stderr.exp | 23 ++++
.../tests/cond_clockwait_invalid.stdout.exp | 0
helgrind/tests/cond_clockwait_invalid.vgtest | 1 +
helgrind/tests/cond_clockwait_test.c | 69 ++++++++++++
helgrind/tests/cond_clockwait_test.stderr.exp | 3 +
helgrind/tests/cond_clockwait_test.stdout.exp | 0
helgrind/tests/cond_clockwait_test.vgtest | 1 +
12 files changed, 270 insertions(+)
create mode 100644 helgrind/tests/cond_clockwait_invalid.c
create mode 100644 helgrind/tests/cond_clockwait_invalid.stderr.exp
create mode 100644 helgrind/tests/cond_clockwait_invalid.stdout.exp
create mode 100644 helgrind/tests/cond_clockwait_invalid.vgtest
create mode 100644 helgrind/tests/cond_clockwait_test.c
create mode 100644 helgrind/tests/cond_clockwait_test.stderr.exp
create mode 100644 helgrind/tests/cond_clockwait_test.stdout.exp
create mode 100644 helgrind/tests/cond_clockwait_test.vgtest
diff --git a/configure.ac b/configure.ac
index 085c98993..8fa81fc7b 100755
--- a/configure.ac
+++ b/configure.ac
@@ -4304,6 +4304,7 @@ AC_CHECK_FUNCS([ \
pthread_spin_lock \
pthread_yield \
pthread_setname_np \
+ pthread_cond_clockwait \
readlinkat \
semtimedop \
signalfd \
diff --git a/drd/drd_pthread_intercepts.c b/drd/drd_pthread_intercepts.c
index c2882e5ab..4730ecf9f 100644
--- a/drd/drd_pthread_intercepts.c
+++ b/drd/drd_pthread_intercepts.c
@@ -1142,6 +1142,32 @@ PTH_FUNCS(int, condZureltimedwait, pthread_cond_timedwait_intercept,
(cond, mutex, timeout));
#endif /* VGO_solaris */
+#if defined(HAVE_PTHREAD_COND_CLOCKWAIT)
+/* POSIX-proposed but for the moment Linux-specific
+ pthread_cond_clockwait() introduced in glibc 2.30. */
+static __always_inline
+int pthread_cond_clockwait_intercept(pthread_cond_t *cond,
+ pthread_mutex_t *mutex,
+ clockid_t clockid,
+ const struct timespec* abstime)
+{
+ int ret;
+ OrigFn fn;
+ VALGRIND_GET_ORIG_FN(fn);
+ VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_COND_WAIT,
+ cond, mutex, DRD_(mutex_type)(mutex), 0, 0);
+ CALL_FN_W_WWWW(ret, fn, cond, mutex, clockid, abstime);
+ VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_COND_WAIT,
+ cond, mutex, 1, 0, 0);
+ return ret;
+}
+
+PTH_FUNCS(int, pthreadZucondZuclockwait, pthread_cond_clockwait_intercept,
+ (pthread_cond_t *cond, pthread_mutex_t *mutex,
+ clockid_t clockid, const struct timespec* abstime),
+ (cond, mutex, clockid, abstime));
+#endif /* HAVE_PTHREAD_COND_CLOCKWAIT */
+
// NOTE: be careful to intercept only pthread_cond_signal() and not Darwin's
// pthread_cond_signal_thread_np(). The former accepts one argument; the latter
// two. Intercepting all pthread_cond_signal* functions will cause only one
diff --git a/helgrind/hg_intercepts.c b/helgrind/hg_intercepts.c
index a10c3a4a3..0f783eef6 100644
--- a/helgrind/hg_intercepts.c
+++ b/helgrind/hg_intercepts.c
@@ -1358,6 +1358,111 @@ static int pthread_cond_timedwait_WRK(pthread_cond_t* cond,
# error "Unsupported OS"
#endif
+#if defined(HAVE_PTHREAD_COND_CLOCKWAIT)
+//-----------------------------------------------------------
+// POSIX-proposed but for the moment only in
+// glibc: pthread_cond_clockwait (since 2.30)
+//
+__attribute__((noinline))
+static int pthread_cond_clockwait_WRK(pthread_cond_t* cond,
+ pthread_mutex_t* mutex,
+ clockid_t clockid,
+ struct timespec* abstime,
+ int timeout_error)
+{
+ int ret;
+ OrigFn fn;
+ unsigned long mutex_is_valid;
+ Bool abstime_is_valid, clockid_is_valid;
+ VALGRIND_GET_ORIG_FN(fn);
+
+ if (TRACE_PTH_FNS) {
+ fprintf(stderr, "<< pthread_cond_clockwait %p %p %u %p",
+ cond, mutex, clockid, abstime);
+ fflush(stderr);
+ }
+
+ /* Tell the tool a cond-wait is about to happen, so it can check
+ for bogus argument values. In return it tells us whether it
+ thinks the mutex is valid or not. */
+ DO_CREQ_W_WW(mutex_is_valid,
+ _VG_USERREQ__HG_PTHREAD_COND_WAIT_PRE,
+ pthread_cond_t*,cond, pthread_mutex_t*,mutex);
+ assert(mutex_is_valid == 1 || mutex_is_valid == 0);
+
+ abstime_is_valid = abstime->tv_nsec >= 0 && abstime->tv_nsec < 1000000000;
+
+ /* Glibc code says that pthread_cond_clockwait() should fail for the
+ "meaningless" CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID
+ and for the "might be meaningful, but are currently unsupported"
+ CLOCK_REALTIME_COARSE, CLOCK_MONOTONIC_RAW, CLOCK_MONOTONIC_COARSE
+ and CLOCK_BOOTTIME clocks. For the moment, let's assume that the
+ only useful clocks are CLOCK_MONOTONIC and CLOCK_REALTIME just
+ because only these two are supported by pthread_condattr_setclock(). */
+ clockid_is_valid =
+#if defined(CLOCK_REALTIME)
+ clockid == CLOCK_REALTIME ||
+#endif
+#if defined(CLOCK_MONOTONIC)
+ clockid == CLOCK_MONOTONIC ||
+#endif
+ 0;
+
+ /* Tell the tool we're about to drop the mutex. This reflects the
+ fact that in a cond_wait, we show up holding the mutex, and the
+ call atomically drops the mutex and waits for the cv to be
+ signalled. */
+ if (mutex_is_valid && clockid_is_valid && abstime_is_valid) {
+ DO_CREQ_v_W(_VG_USERREQ__HG_PTHREAD_MUTEX_UNLOCK_PRE,
+ pthread_mutex_t*,mutex);
+ }
+
+ CALL_FN_W_WWWW(ret, fn, cond, mutex, clockid, abstime);
+
+ if (mutex_is_valid && !abstime_is_valid && ret != EINVAL) {
+ DO_PthAPIerror("Bug in libpthread: pthread_cond_clockwait "
+ "invalid abstime did not cause"
+ " EINVAL", ret);
+ }
+
+ if (mutex_is_valid && !clockid_is_valid && ret != EINVAL) {
+ DO_PthAPIerror("Bug in libpthread: pthread_cond_clockwait "
+ "invalid clockid did not cause"
+ " EINVAL", ret);
+ }
+
+ if (mutex_is_valid && clockid_is_valid && abstime_is_valid) {
+ /* and now we have the mutex again if (ret == 0 || ret == timeout) */
+ DO_CREQ_v_WW(_VG_USERREQ__HG_PTHREAD_MUTEX_LOCK_POST,
+ pthread_mutex_t *, mutex,
+ long, (ret == 0 || ret == timeout_error) ? True : False);
+ }
+
+ DO_CREQ_v_WWWW(_VG_USERREQ__HG_PTHREAD_COND_WAIT_POST,
+ pthread_cond_t*,cond, pthread_mutex_t*,mutex,
+ long,ret == timeout_error,
+ long, (ret == 0 || ret == timeout_error) && mutex_is_valid
+ ? True : False);
+
+ if (ret != 0 && ret != timeout_error) {
+ DO_PthAPIerror( "pthread_cond_clockwait", ret );
+ }
+
+ if (TRACE_PTH_FNS) {
+ fprintf(stderr, " pthread_cond_clockwait -> %d >>\n", ret);
+ }
+
+ return ret;
+}
+
+/* As of glibc-2.32, pthread_cond_clockwait() is not versioned. */
+PTH_FUNC(int, pthreadZucondZuclockwait, // pthread_cond_clockwait
+ pthread_cond_t* cond, pthread_mutex_t* mutex,
+ clockid_t clock, struct timespec* abstime) {
+ return pthread_cond_clockwait_WRK(cond, mutex, clock,
+ abstime, ETIMEDOUT);
+}
+#endif /* HAVE_PTHREAD_COND_CLOCKWAIT */
//-----------------------------------------------------------
// glibc: pthread_cond_signal@GLIBC_2.0
diff --git a/helgrind/tests/Makefile.am b/helgrind/tests/Makefile.am
index ad1af191a..d87689d01 100644
--- a/helgrind/tests/Makefile.am
+++ b/helgrind/tests/Makefile.am
@@ -19,6 +19,10 @@ EXTRA_DIST = \
cond_timedwait_invalid.stderr.exp \
cond_timedwait_test.vgtest cond_timedwait_test.stdout.exp \
cond_timedwait_test.stderr.exp \
+ cond_clockwait_invalid.vgtest cond_clockwait_invalid.stdout.exp \
+ cond_clockwait_invalid.stderr.exp \
+ cond_clockwait_test.vgtest cond_clockwait_test.stdout.exp \
+ cond_clockwait_test.stderr.exp \
bar_bad.vgtest bar_bad.stdout.exp bar_bad.stderr.exp \
bar_bad.stderr.exp-destroy-hang \
bar_trivial.vgtest bar_trivial.stdout.exp bar_trivial.stderr.exp \
@@ -130,6 +134,8 @@ check_PROGRAMS = \
cond_init_destroy \
cond_timedwait_invalid \
cond_timedwait_test \
+ cond_clockwait_invalid \
+ cond_clockwait_test \
free_is_write \
hg01_all_ok \
hg02_deadlock \
diff --git a/helgrind/tests/cond_clockwait_invalid.c b/helgrind/tests/cond_clockwait_invalid.c
new file mode 100644
index 000000000..c055ca6eb
--- /dev/null
+++ b/helgrind/tests/cond_clockwait_invalid.c
@@ -0,0 +1,35 @@
+#include "../../config.h"
+
+#define _GNU_SOURCE 1
+
+#include <time.h>
+#include <pthread.h>
+#include <assert.h>
+#include <errno.h>
+
+int main()
+{
+#if defined(HAVE_PTHREAD_COND_CLOCKWAIT)
+
+ struct timespec abstime;
+ pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+ pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+
+ /* Test for invalid timeout. */
+ abstime.tv_sec = time(NULL) + 1;
+ abstime.tv_nsec = 1000000000;
+ assert(pthread_mutex_lock(&mutex)==0);
+ assert(pthread_cond_clockwait(&cond, &mutex, CLOCK_REALTIME, &abstime)==EINVAL);
+ assert(pthread_mutex_unlock(&mutex)==0);
+
+ /* Test for invalid clock ID. */
+ abstime.tv_sec = time(NULL) + 1;
+ abstime.tv_nsec = 0;
+ assert(pthread_mutex_lock(&mutex)==0);
+ assert(pthread_cond_clockwait(&cond, &mutex, 0x12345678, &abstime)==EINVAL);
+ assert(pthread_mutex_unlock(&mutex)==0);
+
+#endif /* HAVE_PTHREAD_COND_CLOCKWAIT */
+
+ return 0;
+}
diff --git a/helgrind/tests/cond_clockwait_invalid.stderr.exp b/helgrind/tests/cond_clockwait_invalid.stderr.exp
new file mode 100644
index 000000000..048dbb3ab
--- /dev/null
+++ b/helgrind/tests/cond_clockwait_invalid.stderr.exp
@@ -0,0 +1,23 @@
+
+---Thread-Announcement------------------------------------------
+
+Thread #x is the program's root thread
+
+----------------------------------------------------------------
+
+Thread #x's call to pthread_cond_clockwait failed
+ with error code 22 (EINVAL: Invalid argument)
+ at 0x........: pthread_cond_clockwait_WRK (hg_intercepts.c:...)
+ by 0x........: pthread_cond_clockwait (hg_intercepts.c:...)
+ by 0x........: main (cond_clockwait_invalid.c:22)
+
+----------------------------------------------------------------
+
+Thread #x's call to pthread_cond_clockwait failed
+ with error code 22 (EINVAL: Invalid argument)
+ at 0x........: pthread_cond_clockwait_WRK (hg_intercepts.c:...)
+ by 0x........: pthread_cond_clockwait (hg_intercepts.c:...)
+ by 0x........: main (cond_clockwait_invalid.c:29)
+
+
+ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
diff --git a/helgrind/tests/cond_clockwait_invalid.stdout.exp b/helgrind/tests/cond_clockwait_invalid.stdout.exp
new file mode 100644
index 000000000..e69de29bb
diff --git a/helgrind/tests/cond_clockwait_invalid.vgtest b/helgrind/tests/cond_clockwait_invalid.vgtest
new file mode 100644
index 000000000..3c9588788
--- /dev/null
+++ b/helgrind/tests/cond_clockwait_invalid.vgtest
@@ -0,0 +1 @@
+prog: cond_clockwait_invalid
diff --git a/helgrind/tests/cond_clockwait_test.c b/helgrind/tests/cond_clockwait_test.c
new file mode 100644
index 000000000..de3f46833
--- /dev/null
+++ b/helgrind/tests/cond_clockwait_test.c
@@ -0,0 +1,69 @@
+#include "../../config.h"
+
+#define _GNU_SOURCE 1
+
+#include <errno.h>
+#include <assert.h>
+#include <pthread.h>
+
+#if defined(HAVE_PTHREAD_COND_CLOCKWAIT)
+
+#define EXPECTED 0x12345678
+
+int global;
+
+typedef struct {
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ int value;
+} value_t;
+
+void *writer(void *arg)
+{
+ value_t *v = arg;
+ struct timespec ts = { 1, 0 };
+
+ assert(pthread_mutex_lock(&v->mutex) == 0);
+ assert(clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL) == 0);
+ v->value = EXPECTED;
+ assert(pthread_cond_signal(&v->cond) == 0);
+ assert(pthread_mutex_unlock(&v->mutex) == 0);
+
+ return NULL;
+}
+
+void *reader(void *arg)
+{
+ value_t *v = arg;
+ struct timespec ts = { time(NULL) + 3, 0 };
+
+ assert(pthread_mutex_lock(&v->mutex) == 0);
+ assert(pthread_cond_clockwait(&v->cond, &v->mutex, CLOCK_REALTIME, &ts) == 0);
+ global = v->value;
+ assert(pthread_mutex_unlock(&v->mutex) == 0);
+
+ return NULL;
+}
+
+int main(void)
+{
+ pthread_t rd, wr;
+ value_t v = { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0 };
+
+ assert(pthread_create(&rd, NULL, reader, &v) == 0);
+ assert(pthread_create(&wr, NULL, writer, &v) == 0);
+ assert(pthread_join(rd, NULL) == 0);
+ assert(pthread_join(wr, NULL) == 0);
+
+ assert(global == EXPECTED);
+ return 0;
+}
+
+#else /* !HAVE_PTHREAD_COND_CLOCKWAIT */
+
+int main(void)
+{
+ return 0;
+}
+
+#endif /* HAVE_PTHREAD_COND_CLOCKWAIT */
diff --git a/helgrind/tests/cond_clockwait_test.stderr.exp b/helgrind/tests/cond_clockwait_test.stderr.exp
new file mode 100644
index 000000000..d18786f80
--- /dev/null
+++ b/helgrind/tests/cond_clockwait_test.stderr.exp
@@ -0,0 +1,3 @@
+
+
+ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
diff --git a/helgrind/tests/cond_clockwait_test.stdout.exp b/helgrind/tests/cond_clockwait_test.stdout.exp
new file mode 100644
index 000000000..e69de29bb
diff --git a/helgrind/tests/cond_clockwait_test.vgtest b/helgrind/tests/cond_clockwait_test.vgtest
new file mode 100644
index 000000000..3bcfccb75
--- /dev/null
+++ b/helgrind/tests/cond_clockwait_test.vgtest
@@ -0,0 +1 @@
+prog: cond_clockwait_test
--
2.26.2
|
|
From: Bart V. A. <bva...@ac...> - 2020-10-01 03:36:27
|
On 2020-09-30 05:29, Dmitry Antipov wrote: > -- > Dmitry Please add a regression test that calls pthread_cond_clockwait() such that the code added by this patch is tested when running the regression tests. Additionally, please use git send-email when posting patches instead of sending these as an attachment. It is much easier to reply to an inline patch than to comment on an attachment. Thanks, Bart. |