Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreutarass2010-03-10 01:18:55 +0000
committereutarass2010-03-10 01:18:55 +0000
commit1e87a684645553f95359b81b27c54525e7d3ff61 (patch)
tree251a87a799429076b6d31b4eda9a2abf4cd7a7dc /framework/cache.c
parenta53eba17a4a7b83f4a56c011006d497194e5261d (diff)
downloadorg.eclipse.tcf.agent-1e87a684645553f95359b81b27c54525e7d3ff61.tar.gz
org.eclipse.tcf.agent-1e87a684645553f95359b81b27c54525e7d3ff61.tar.xz
org.eclipse.tcf.agent-1e87a684645553f95359b81b27c54525e7d3ff61.zip
TCF Agent: more symbols value-add code.
Diffstat (limited to 'framework/cache.c')
-rw-r--r--framework/cache.c49
1 files changed, 35 insertions, 14 deletions
diff --git a/framework/cache.c b/framework/cache.c
index b51c6f9f..5a118553 100644
--- a/framework/cache.c
+++ b/framework/cache.c
@@ -29,41 +29,55 @@ typedef struct WaitingCacheClient {
CacheClient * client;
Channel * channel;
void * args;
+ size_t args_size;
+ int args_copy;
} WaitingCacheClient;
-static WaitingCacheClient current_client = {0, 0, 0};
+static WaitingCacheClient current_client = {0, 0, 0, 0, 0};
+static int client_exited = 0;
static int cache_miss_cnt = 0;
static WaitingCacheClient * wait_list_buf;
static unsigned wait_list_max;
-void cache_enter(CacheClient * client, Channel * channel, void * args) {
+static void run_cache_client(void) {
Trap trap;
+ OutputStream * out = &current_client.channel->bcg->out;
- assert(is_dispatch_thread());
- assert(client != NULL);
- assert(channel != NULL);
- assert(current_client.client == NULL);
- current_client.client = client;
- current_client.channel = channel;
- current_client.args = args;
cache_miss_cnt = 0;
+ client_exited = 0;
if (set_trap(&trap)) {
- client(args);
+ current_client.client(current_client.args);
clear_trap(&trap);
assert(cache_miss_cnt == 0);
- flush_stream(&channel->bcg->out);
+ assert(client_exited);
+ flush_stream(out);
}
- else if (get_error_code(trap.error) != ERR_CACHE_MISS || current_client.client == NULL) {
+ else if (get_error_code(trap.error) != ERR_CACHE_MISS || client_exited) {
trace(LOG_ALWAYS, "Unhandled exception in data cache client: %d %s", trap.error, errno_to_str(trap.error));
}
+ if (cache_miss_cnt == 0 && current_client.args_copy) loc_free(current_client.args);
memset(&current_client, 0, sizeof(current_client));
}
+void cache_enter(CacheClient * client, Channel * channel, void * args, size_t args_size) {
+ assert(is_dispatch_thread());
+ assert(client != NULL);
+ assert(channel != NULL);
+ assert(current_client.client == NULL);
+ current_client.client = client;
+ current_client.channel = channel;
+ current_client.args = args;
+ current_client.args_size = args_size;
+ current_client.args_copy = 0;
+ run_cache_client();
+}
+
void cache_exit(void) {
assert(is_dispatch_thread());
assert(current_client.client != NULL);
+ assert(!client_exited);
if (cache_miss_cnt > 0) exception(ERR_CACHE_MISS);
- memset(&current_client, 0, sizeof(current_client));
+ client_exited = 1;
}
void cache_wait(AbstractCache * cache) {
@@ -73,6 +87,12 @@ void cache_wait(AbstractCache * cache) {
cache->wait_list_max += 8;
cache->wait_list_buf = (WaitingCacheClient *)loc_realloc(cache->wait_list_buf, cache->wait_list_max * sizeof(WaitingCacheClient));
}
+ if (current_client.args != NULL && !current_client.args_copy) {
+ void * mem = loc_alloc(current_client.args_size);
+ memcpy(mem, current_client.args, current_client.args_size);
+ current_client.args = mem;
+ current_client.args_copy = 1;
+ }
cache->wait_list_buf[cache->wait_list_cnt++] = current_client;
channel_lock(current_client.channel);
}
@@ -92,7 +112,8 @@ void cache_notify(AbstractCache * cache) {
}
memcpy(wait_list_buf, cache->wait_list_buf, cnt * sizeof(WaitingCacheClient));
for (i = 0; i < cnt; i++) {
- cache_enter(wait_list_buf[i].client, wait_list_buf[i].channel, wait_list_buf[i].args);
+ current_client = wait_list_buf[i];
+ run_cache_client();
channel_unlock(wait_list_buf[i].channel);
}
}

Back to the top