size_t args_size; int args_copy; #ifndef NDEBUG time_t time_stamp; const char * file; int line; #endif } WaitingCacheClient; static WaitingCacheClient current_client = {0, 0, 0, 0, 0, 0}; static AbstractCache * current_cache = NULL; static int cache_miss_cnt = 0; static WaitingCacheClient * wait_list_buf; static unsigned wait_list_max; static unsigned id_cnt = 0; 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 /* Print cache items that are waiting too long to be filled. * In most cases such items indicate a bug in the agent code. */ static int cache_timer_posted = 0; static void cache_timer(void * x) {
typedef struct Terminal { LINK link; TCFBroadcastGroup * bcg; ChildProcess * prs; char pty_type[TERM_PROP_DEF_SIZE]; char encoding[TERM_PROP_DEF_SIZE]; int terminated; Channel * channel; } Terminal; #define link2term(A) ((Terminal *)((char *)(A) - offsetof(Terminal, link))) static LINK terms_list = TCF_LIST_INIT(terms_list); static Terminal * find_terminal(int pid) { LINK * qhp = &terms_list; LINK * qp = qhp->next; while (qp != qhp) { Terminal * term = link2term(qp); if (get_process_pid(term->prs) == pid) return term; qp = qp->next; } return NULL; } static char * tid2id(int tid) { static char s[64];
LINK servlink; ServerInstance arr[SERVER_INSTANCE_CNT]; }; static size_t channel_pipe_extension_offset = 0; #define EXT(ctx) ((ChannelPIPE **)((char *)(ctx) + channel_pipe_extension_offset)) #define channel2pipe(A) (*EXT(A)) #define inp2channel(A) ((Channel *)((char *)(A) - offsetof(Channel, inp))) #define out2channel(A) ((Channel *)((char *)(A) - offsetof(Channel, out))) #define server2pipe(A) ((ServerPIPE *)((char *)(A) - offsetof(ServerPIPE, serv))) #define servlink2pipe(A) ((ServerPIPE *)((char *)(A) - offsetof(ServerPIPE, servlink))) #define ibuf2pipe(A) ((ChannelPIPE *)((char *)(A) - offsetof(ChannelPIPE, ibuf))) #define obuf2pipe(A) ((ChannelPIPE *)((char *)(A) - offsetof(ChannelPIPE, out_queue))) static LINK server_list = TCF_LIST_INIT(server_list); static void pipe_read_done(void * x); static void handle_channel_msg(void * x); static void close_input_pipe(ChannelPIPE * c); static void close_output_pipe(ChannelPIPE * c); static void delete_channel(ChannelPIPE * c) { trace(LOG_PROTOCOL, "Deleting channel %#lx", c); assert(c->lock_cnt == 0); assert(c->out_flush_cnt == 0); assert(c->magic == CHANNEL_MAGIC); assert(c->read_pending == 0); assert(c->ibuf.handling_msg != HandleMsgTriggered); assert(output_queue_is_empty(&c->out_queue)); output_queue_clear(&c->out_queue);
#include <tcf/framework/trace.h> #include <tcf/framework/events.h> #include <tcf/framework/errors.h> #include <tcf/framework/link.h> #include <tcf/framework/asyncreq.h> #include <tcf/framework/shutdown.h> #ifndef MAX_WORKER_THREADS #define MAX_WORKER_THREADS 32 #endif #ifndef EVENTS_TIMER_RESOLUTION #define EVENTS_TIMER_RESOLUTION 50 #endif static LINK wtlist = TCF_LIST_INIT(wtlist); static int wtlist_size = 0; static int wtrunning_count = 0; static pthread_mutex_t wtlock; typedef struct WorkerThread { LINK wtlink; AsyncReqInfo * req; pthread_cond_t cond; pthread_t thread; } WorkerThread; #define wtlink2wt(A) ((WorkerThread *)((char *)(A) - offsetof(WorkerThread, wtlink))) #define AsyncReqTimer -1
# define ENABLE_FastMemAlloc 1 #endif #if !defined(USE_libc_malloc) # define USE_libc_malloc 1 #endif #if ENABLE_FastMemAlloc #define POOL_SIZE (0xfff0 * MEM_USAGE_FACTOR) static char * tmp_pool = NULL; static size_t tmp_pool_pos = 0; static size_t tmp_pool_max = 0; static size_t tmp_pool_avr = 0; #endif static LINK tmp_alloc_list = TCF_LIST_INIT(tmp_alloc_list); static size_t tmp_alloc_size = 0; static int tmp_gc_posted = 0; static void gc_event(void * args) { tmp_gc_posted = 0; tmp_gc(); } void tmp_gc(void) { #if ENABLE_FastMemAlloc if (tmp_pool_pos + tmp_alloc_size >= tmp_pool_avr) { tmp_pool_avr = tmp_pool_pos + tmp_alloc_size; } else if (tmp_pool_avr > POOL_SIZE / 0x10) { tmp_pool_avr -= POOL_SIZE / 0x10000;
ContextAddress syscall_pc; ContextAddress loader_state; int end_of_step; REG_SET * regs; /* copy of context registers, updated when context stops */ ErrorReport * regs_error; /* if not NULL, 'regs' is invalid */ int regs_dirty; /* if not 0, 'regs' is modified and needs to be saved before context is continued */ int pending_step; } ContextExtensionDarwin; static size_t context_extension_offset = 0; #define EXT(ctx) ((ContextExtensionDarwin *)((char *)(ctx) + context_extension_offset)) #include <tcf/framework/pid-hash.h> static LINK pending_list = TCF_LIST_INIT(pending_list); static MemoryErrorInfo mem_err_info; const char * context_suspend_reason(Context * ctx) { static char reason[128]; if (EXT(ctx)->end_of_step) return REASON_STEP; if (EXT(ctx)->syscall_enter) return "System Call"; if (EXT(ctx)->syscall_exit) return "System Return"; if (ctx->signal == SIGSTOP || ctx->signal == SIGTRAP) return REASON_USER_REQUEST; snprintf(reason, sizeof(reason), "Signal %d", ctx->signal); return reason; } int context_attach_self(void) {
LINK link_all; char type[256]; Channel * channel; }; #define hash2client(A) ((StreamClient *)((char *)(A) - offsetof(StreamClient, link_hash))) #define stream2client(A) ((StreamClient *)((char *)(A) - offsetof(StreamClient, link_stream))) #define all2client(A) ((StreamClient *)((char *)(A) - offsetof(StreamClient, link_all))) #define all2subscription(A) ((Subscription *)((char *)(A) - offsetof(Subscription, link_all))) #define all2stream(A) ((VirtualStream *)((char *)(A) - offsetof(VirtualStream, link_all))) #define client2read_request(A) ((ReadRequest *)((char *)(A) - offsetof(ReadRequest, link_client))) #define client2write_request(A) ((WriteRequest *)((char *)(A) - offsetof(WriteRequest, link_client))) #define HANDLE_HASH_SIZE (4 * MEM_USAGE_FACTOR - 1) static LINK handle_hash[HANDLE_HASH_SIZE]; static LINK clients = TCF_LIST_INIT(clients); static LINK streams = TCF_LIST_INIT(streams); static LINK subscriptions = TCF_LIST_INIT(subscriptions); static unsigned id_cnt = 0; static unsigned get_client_hash(unsigned id, Channel * c) { return (id + (unsigned)(uintptr_t)c) % HANDLE_HASH_SIZE; } static int str2id(char * s, unsigned * id) { const char * stream_base_id = STREAM_BASE_ID; char * p = NULL; while (*stream_base_id != 0) { if (*s++ != *stream_base_id++) return 0; } *id = (unsigned)strtoul(s, &p, 10);