Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2014-07-09 01:29:24 -0400
committerEugene Tarassov2014-07-09 01:29:24 -0400
commit633537109c00aa9a8fb79e2d37b08bbde7b1b30e (patch)
treed3ae4d1d46623ee8ee96930efef5024cdf182b66
parente604a1e9c77c7f87f727f19d53a73d1fc7ba01f7 (diff)
downloadorg.eclipse.tcf.agent-633537109c00aa9a8fb79e2d37b08bbde7b1b30e.tar.gz
org.eclipse.tcf.agent-633537109c00aa9a8fb79e2d37b08bbde7b1b30e.tar.xz
org.eclipse.tcf.agent-633537109c00aa9a8fb79e2d37b08bbde7b1b30e.zip
Bug 438842 - Dynamic Printf displays the message multiple times
-rw-r--r--agent/tcf/framework/cache.c24
-rw-r--r--agent/tcf/framework/cache.h12
-rw-r--r--agent/tcf/services/dprintf.c67
3 files changed, 74 insertions, 29 deletions
diff --git a/agent/tcf/framework/cache.c b/agent/tcf/framework/cache.c
index 836d1e2f..64b2ed37 100644
--- a/agent/tcf/framework/cache.c
+++ b/agent/tcf/framework/cache.c
@@ -51,6 +51,10 @@ static LINK cache_list = TCF_LIST_INIT(cache_list);
static Channel * def_channel = NULL;
static const char * channel_lock_msg = "Cache client lock";
+static CacheTransactionListener ** listeners = NULL;
+static unsigned listeners_cnt = 0;
+static unsigned listeners_max = 0;
+
#define link_all2cache(x) ((AbstractCache *)((char *)(x) - offsetof(AbstractCache, link)))
#ifndef NDEBUG
@@ -83,12 +87,14 @@ static void cache_timer(void * x) {
}
#endif
-static void run_cache_client(void) {
+static void run_cache_client(int retry) {
Trap trap;
+ unsigned i;
cache_miss_cnt = 0;
client_exited = 0;
def_channel = NULL;
+ for (i = 0; i < listeners_cnt; i++) listeners[i](retry ? CTLE_RETRY : CTLE_START);
if (set_trap(&trap)) {
current_client.client(current_client.args);
clear_trap(&trap);
@@ -98,6 +104,7 @@ static void run_cache_client(void) {
else if (get_error_code(trap.error) != ERR_CACHE_MISS || client_exited || cache_miss_cnt == 0) {
trace(LOG_ALWAYS, "Unhandled exception in data cache client: %d %s", trap.error, errno_to_str(trap.error));
}
+ for (i = 0; i < listeners_cnt; i++) listeners[i](client_exited ? CTLE_COMMIT : CTLE_ABORT);
if (cache_miss_cnt == 0 && current_client.args_copy) loc_free(current_client.args);
memset(&current_client, 0, sizeof(current_client));
cache_miss_cnt = 0;
@@ -117,7 +124,7 @@ void cache_enter(CacheClient * client, Channel * channel, void * args, size_t ar
current_client.args = args;
current_client.args_size = args_size;
current_client.args_copy = 0;
- run_cache_client();
+ run_cache_client(0);
}
void cache_exit(void) {
@@ -183,7 +190,7 @@ void cache_notify(AbstractCache * cache) {
memcpy(wait_list_buf, cache->wait_list_buf, cnt * sizeof(WaitingCacheClient));
for (i = 0; i < cnt; i++) {
current_client = wait_list_buf[i];
- run_cache_client();
+ run_cache_client(1);
if (wait_list_buf[i].channel != NULL) channel_unlock_with_msg(wait_list_buf[i].channel, channel_lock_msg);
}
}
@@ -193,7 +200,7 @@ static void cache_notify_event(void * args) {
WaitingCacheClient * buf = (WaitingCacheClient *)args;
for (i = 0; buf[i].client != NULL; i++) {
current_client = buf[i];
- run_cache_client();
+ run_cache_client(1);
if (buf[i].channel != NULL) channel_unlock_with_msg(buf[i].channel, channel_lock_msg);
}
loc_free(buf);
@@ -236,6 +243,15 @@ unsigned cache_miss_count(void) {
return cache_miss_cnt;
}
+void add_cache_transaction_listener(CacheTransactionListener * l) {
+ if (listeners_cnt >= listeners_max) {
+ listeners_max += 8;
+ listeners = (CacheTransactionListener **)loc_realloc(listeners,
+ sizeof(CacheTransactionListener *) * listeners_max);
+ }
+ listeners[listeners_cnt++] = l;
+}
+
void cache_dispose(AbstractCache * cache) {
assert(is_dispatch_thread());
assert(cache->wait_list_cnt == 0);
diff --git a/agent/tcf/framework/cache.h b/agent/tcf/framework/cache.h
index 7ba5c35b..3ddd34dd 100644
--- a/agent/tcf/framework/cache.h
+++ b/agent/tcf/framework/cache.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2013 Wind River Systems, Inc. and others.
+ * Copyright (c) 2009, 2014 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
@@ -172,6 +172,16 @@ extern unsigned cache_transaction_id(void);
extern unsigned cache_miss_count(void);
/*
+ * Cache transaction listeners.
+ */
+#define CTLE_START 1
+#define CTLE_RETRY 2
+#define CTLE_ABORT 3
+#define CTLE_COMMIT 4
+typedef void CacheTransactionListener(int /* event */);
+extern void add_cache_transaction_listener(CacheTransactionListener * l);
+
+/*
* Dispose a cache.
*/
extern void cache_dispose(AbstractCache * cache);
diff --git a/agent/tcf/services/dprintf.c b/agent/tcf/services/dprintf.c
index e0f50415..5c8ba9a9 100644
--- a/agent/tcf/services/dprintf.c
+++ b/agent/tcf/services/dprintf.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 Xilinx, Inc. and others.
+ * Copyright (c) 2013, 2014 Xilinx, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
@@ -59,6 +59,7 @@ static LINK clients;
static char * buf = NULL;
static unsigned buf_pos = 0;
static unsigned buf_max = 0;
+static Client * buf_client = NULL;
static Client * find_client(Channel * channel) {
LINK * l;
@@ -106,15 +107,10 @@ static const void * load_remote_string(Context * ctx, Value * arg_val) {
}
void dprintf_expression_ctx(Context * ctx, const char * fmt, Value * args, unsigned args_cnt) {
- Client * client = find_client(cache_channel());
unsigned fmt_pos = 0;
unsigned arg_pos = 0;
- if (client == NULL) return;
-
- buf = NULL;
- buf_pos = 0;
- buf_max = 0;
+ if (buf_client == NULL) return;
while (fmt[fmt_pos]) {
char ch = fmt[fmt_pos];
@@ -238,18 +234,6 @@ void dprintf_expression_ctx(Context * ctx, const char * fmt, Value * args, unsig
add_ch(ch);
fmt_pos++;
}
- if (buf_pos > 0) {
- size_t done = 0;
- virtual_stream_add_data(client->vstream, buf, buf_pos, &done, 0);
- if (done < buf_pos) {
- Buffer * b = (Buffer *)loc_alloc_zero(sizeof(Buffer));
- b->size = buf_pos - done;
- b->buf = (char *)loc_alloc(b->size);
- memcpy(b->buf, buf + done, b->size);
- if (list_is_empty(&client->bufs)) run_ctrl_lock();
- list_add_last(&b->link, &client->bufs);
- }
- }
}
static void streams_callback(VirtualStream * stream, int event_code, void * args) {
@@ -302,11 +286,15 @@ static void command_open(char * token, Channel * c) {
static void free_client(Client * client) {
virtual_stream_delete(client->vstream);
list_remove(&client->link);
- while (!list_is_empty(&client->bufs)) {
- Buffer * bf = link2buf(client->bufs.next);
- list_remove(&bf->link);
- loc_free(bf->buf);
- loc_free(bf);
+ if (!list_is_empty(&client->bufs)) {
+ do {
+ Buffer * bf = link2buf(client->bufs.next);
+ list_remove(&bf->link);
+ loc_free(bf->buf);
+ loc_free(bf);
+ }
+ while (!list_is_empty(&client->bufs));
+ run_ctrl_unlock();
}
loc_free(client);
}
@@ -324,6 +312,36 @@ static void command_close(char * token, Channel * c) {
write_stream(&c->out, MARKER_EOM);
}
+static void cache_transaction_listener(int evt) {
+ switch (evt) {
+ case CTLE_START:
+ case CTLE_RETRY:
+ buf_client = find_client(cache_channel());
+ break;
+ case CTLE_ABORT:
+ buf_client = NULL;
+ break;
+ case CTLE_COMMIT:
+ if (buf_pos > 0) {
+ size_t done = 0;
+ virtual_stream_add_data(buf_client->vstream, buf, buf_pos, &done, 0);
+ if (done < buf_pos) {
+ Buffer * b = (Buffer *)loc_alloc_zero(sizeof(Buffer));
+ b->size = buf_pos - done;
+ b->buf = (char *)loc_alloc(b->size);
+ memcpy(b->buf, buf + done, b->size);
+ if (list_is_empty(&buf_client->bufs)) run_ctrl_lock();
+ list_add_last(&b->link, &buf_client->bufs);
+ }
+ }
+ buf_client = NULL;
+ break;
+ }
+ buf = NULL;
+ buf_pos = 0;
+ buf_max = 0;
+}
+
static void channel_close_listener(Channel * c) {
Client * client = find_client(c);
if (client != NULL) free_client(client);
@@ -355,6 +373,7 @@ void ini_dprintf_service(Protocol * p) {
list_init(&clients);
add_command_handler(p, DPRINTF, "open", command_open);
add_command_handler(p, DPRINTF, "close", command_close);
+ add_cache_transaction_listener(cache_transaction_listener);
add_channel_close_listener(channel_close_listener);
add_identifier_callback(identifier_callback);
}

Back to the top