static ChannelServer * channel_server_create(PeerServer * ps, noPollCtx * np_ctx, noPollConn * np_listener, int is_ssl) {
    ServerNP * si = (ServerNP *)loc_alloc_zero(sizeof *si);
    /* TODO: need to investigate usage of sizeof(sockaddr_storage) for address buffer size */
    si->serv.close = server_close;
    si->sock = nopoll_conn_socket(np_listener);
    si->serv.ps = ps;
    if (server_list.next == NULL) {
        list_init(&server_list);
        post_event_with_delay(refresh_all_peer_servers, NULL, PEER_DATA_REFRESH_PERIOD * 1000000);
    }
    list_add_last(&si->serv.servlink, &channel_server_root);
    shutdown_set_normal(&channel_shutdown);
    list_add_last(&si->servlink, &server_list);
    refresh_peer_server(si->sock, ps);


    si->accreq.done = np_server_accept_done;
    si->accreq.u.user.data = si;
    si->accreq.u.user.func = np_wt_accept;
    si->accreq.client_data = si;
    si->accreq.type = AsyncReqUser;

    si->np_listener = np_listener;
    si->np_ctx = np_ctx;
    si->is_ssl = is_ssl;
    async_req_post(&si->accreq);
    return &si->serv;
}
Пример #2
0
void * tmp_alloc(size_t size) {
    void * p;
    LINK * l;
    assert(is_dispatch_thread());
    if (!tmp_gc_posted) {
        post_event(gc_event, NULL);
        tmp_gc_posted = 1;
    }
#if ENABLE_FastMemAlloc
    if (tmp_pool_pos + size + ALIGNMENT + sizeof(size_t *) > tmp_pool_max) {
        if (tmp_pool != NULL) {
            l = (LINK *)tmp_pool;
            list_add_last(l, &tmp_alloc_list);
            tmp_alloc_size += tmp_pool_pos;
        }
        tmp_pool_max = POOL_SIZE / 0x10 + size;
        tmp_pool = (char *)loc_alloc(tmp_pool_max);
        tmp_pool_pos = sizeof(LINK);
    }
    tmp_pool_pos += sizeof(size_t *);
    tmp_pool_pos = (tmp_pool_pos + ALIGNMENT - 1) & ~(ALIGNMENT - 1);
    p = tmp_pool + tmp_pool_pos;
    *((size_t *)p - 1) = size;
    tmp_pool_pos += size;
    return p;
#else
    l = (LINK *)loc_alloc(sizeof(LINK) + size);
    list_add_last(l, &tmp_alloc_list);
    tmp_alloc_size += size + ALIGNMENT + sizeof(size_t *);
    p = l + 1;
    return p;
#endif
}
Пример #3
0
void cache_wait(AbstractCache * cache) {
#else
void cache_wait_dbg(const char * file, int line, AbstractCache * cache) {
#endif
    assert(is_dispatch_thread());
    assert(client_exited == 0);
    if (current_client.client != NULL && cache_miss_cnt == 0) {
        if (cache->wait_list_cnt >= cache->wait_list_max) {
            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;
        }
#ifndef NDEBUG
        current_client.file = file;
        current_client.line = line;
#endif
        if (cache->wait_list_cnt == 0) list_add_last(&cache->link, &cache_list);
        cache->wait_list_buf[cache->wait_list_cnt++] = current_client;
        channel_lock(current_client.channel);
    }
#ifndef NDEBUG
    else if (current_client.client == NULL) {
        trace(LOG_ALWAYS, "cache_wait(): illegal cache access at %s:%d", file, line);
    }
#endif
    cache_miss_cnt++;
    exception(ERR_CACHE_MISS);
}
Пример #4
0
int virtual_stream_eos(Channel * c, char * token, char * id) {
    size_t done = 0;
    WriteRequest * r = NULL;
    int err = 0;
    StreamClient * client = find_client(id, c);

    if (client == NULL) err = errno;
    if (!err && (client->stream->access & VS_ENABLE_REMOTE_WRITE) == 0) err = ERR_UNSUPPORTED;
    if (!err && !list_is_empty(&client->write_requests)) r = (WriteRequest *)loc_alloc_zero(sizeof(WriteRequest));
    if (!err && r == NULL && virtual_stream_add_data(client->stream, NULL, 0, &done, 1) < 0) err = errno;

    if (r != NULL) {
        list_init(&r->link_client);
        r->client = client;
        r->eos = 1;
        strlcpy(r->token, token, sizeof(r->token));
        list_add_last(&r->link_client, &client->write_requests);
    }
    else if (err == 0) {
        write_stringz(&c->out, "R");
        write_stringz(&c->out, token);
        write_errno(&c->out, err);
        write_stream(&c->out, MARKER_EOM);
    }

    if (err != 0) errno = err;

    return err == 0 ? 0 : -1;
}
Пример #5
0
int virtual_stream_read(Channel * c, char * token, char * id, size_t size) {
    int err = 0;
    StreamClient * client = find_client(id, c);

    if (client == NULL) err = errno;
    if (!err && (client->stream->access & VS_ENABLE_REMOTE_READ) == 0) err = ERR_UNSUPPORTED;

    if (err == 0) {
        VirtualStream * stream = client->stream;
        if (client->pos == stream->pos && !stream->eos_inp) {
            ReadRequest * r = (ReadRequest *)loc_alloc_zero(sizeof(ReadRequest));
            list_init(&r->link_client);
            r->client = client;
            r->size = size;
            strlcpy(r->token, token, sizeof(r->token));
            list_add_last(&r->link_client, &client->read_requests);
        }
        else {
            assert(list_is_empty(&client->read_requests));
            assert(client->channel == c);
            send_read_reply(client, token, size);
            advance_stream_buffer(stream);
        }
    }
    else errno = err;

    return err == 0 ? 0 : -1;
}
Пример #6
0
/** add item to any position
 */
void list_add (linked_list* _this, void* item, int position) {
     // index out of list size
     if (position > _this->size) {
       return;
    }
    // add to head
    if (position == 0) {
        list_add_first(_this, item);
    } else if (position == _this->size) {
        // add to tail
        list_add_last(_this, item);
    } else {
        // insert between head and tail

       node* n = _this->head;
        int i = 0;
        // loop until the position
        while (i < position) {
            n = n->next;
            i++;
        }
        // insert new node to position
        node* newNode = list_create_node(item);
        list_insert_before(_this, n, newNode);
        _this->size++;
    }
}
static void command_eos(char * token, Channel * c) {
    char id[256];
    StreamClient * client = NULL;
    size_t done = 0;
    WriteRequest * r = NULL;
    int err = 0;

    json_read_string(&c->inp, id, sizeof(id));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    client = find_client(id, c);
    if (client == NULL) err = errno;
    if (!err && (client->stream->access & VS_ENABLE_REMOTE_WRITE) == 0) err = ERR_UNSUPPORTED;
    if (!err && !list_is_empty(&client->write_requests)) r = loc_alloc_zero(sizeof(WriteRequest));
    if (!err && r == NULL && virtual_stream_add_data(client->stream, NULL, 0, &done, 1) < 0) err = errno;

    if (r != NULL) {
        list_init(&r->link_client);
        r->client = client;
        r->eos = 1;
        strncpy(r->token, token, sizeof(r->token) - 1);
        list_add_last(&r->link_client, &client->write_requests);
    }
    else {
        write_stringz(&c->out, "R");
        write_stringz(&c->out, token);
        write_errno(&c->out, err);
        write_stream(&c->out, MARKER_EOM);
    }
}
Пример #8
0
void * tmp_realloc(void * ptr, size_t size) {
    if (ptr == NULL) return tmp_alloc(size);
    assert(is_dispatch_thread());
    assert(tmp_gc_posted);
#if ENABLE_FastMemAlloc
    {
        void * p;
        size_t m = *((size_t *)ptr - 1);
        if (m >= size) return ptr;
        if ((char *)ptr >= tmp_pool && (char *)ptr <= tmp_pool + tmp_pool_max) {
            size_t pos = tmp_pool_pos - m;
            if (ptr == tmp_pool + pos && pos + size <= tmp_pool_max) {
                tmp_pool_pos = pos + size;
                *((size_t *)ptr - 1) = size;
                return ptr;
            }
        }
        p = tmp_alloc(size);
        if (m > size) m = size;
        return memcpy(p, ptr, m);
    }
#else
    {
        LINK * l = (LINK *)ptr - 1;
        list_remove(l);
        l = (LINK *)loc_realloc(l, sizeof(LINK) + size);
        list_add_last(l, &tmp_alloc_list);
        return l + 1;
    }
#endif
}
Пример #9
0
static IORequest * create_io_request(char * token, OpenFileInfo * handle, int type) {
    IORequest * req = loc_alloc_zero(sizeof(IORequest));
    req->req = type;
    req->handle = handle;
    req->info.done = done_io_request;
    req->info.client_data = req;
    strncpy(req->token, token, sizeof(req->token) - 1);
    list_add_last(&req->link_reqs, &handle->link_reqs);
    return req;
}
Пример #10
0
static void run_cache_client(int retry) {
    Trap trap;
    unsigned i;
    unsigned id = current_client.id;
    void * args_copy = NULL;

    assert(id != 0);
    current_cache = NULL;
    cache_miss_cnt = 0;
    def_channel = NULL;
    if (current_client.args_copy) args_copy = current_client.args;
    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);
        assert(current_client.id == 0);
        assert(cache_miss_cnt == 0);
    }
    else if (id != current_client.id) {
        trace(LOG_ALWAYS, "Unhandled exception in data cache client: %s", errno_to_str(trap.error));
        assert(current_client.id == 0);
        assert(cache_miss_cnt == 0);
    }
    else {
        if (get_error_code(trap.error) != ERR_CACHE_MISS || cache_miss_cnt == 0 || current_cache == NULL) {
            trace(LOG_ALWAYS, "Unhandled exception in data cache client: %s", errno_to_str(trap.error));
            for (i = 0; i < listeners_cnt; i++) listeners[i](CTLE_COMMIT);
        }
        else {
            AbstractCache * cache = current_cache;
            if (cache->wait_list_cnt >= cache->wait_list_max) {
                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;
            }
            if (cache->wait_list_cnt == 0) list_add_last(&cache->link, &cache_list);
            if (current_client.channel != NULL) channel_lock_with_msg(current_client.channel, channel_lock_msg);
            cache->wait_list_buf[cache->wait_list_cnt++] = current_client;
            for (i = 0; i < listeners_cnt; i++) listeners[i](CTLE_ABORT);
            args_copy = NULL;
        }
        memset(&current_client, 0, sizeof(current_client));
        current_cache = NULL;
        cache_miss_cnt = 0;
        def_channel = NULL;
    }
    if (args_copy != NULL) loc_free(args_copy);
}
static void command_read(char * token, Channel * c) {
    char id[256];
    size_t size = 0;
    StreamClient * client = NULL;
    int err = 0;

    json_read_string(&c->inp, id, sizeof(id));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    size = json_read_ulong(&c->inp);
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    client = find_client(id, c);
    if (client == NULL) err = errno;
    if (!err && (client->stream->access & VS_ENABLE_REMOTE_READ) == 0) err = ERR_UNSUPPORTED;

    if (err == 0) {
        VirtualStream * stream = client->stream;
        if (client->pos == stream->pos && !stream->eos) {
            ReadRequest * r = loc_alloc_zero(sizeof(ReadRequest));
            list_init(&r->link_client);
            r->client = client;
            r->size = size;
            strncpy(r->token, token, sizeof(r->token) - 1);
            list_add_last(&r->link_client, &client->read_requests);
        }
        else {
            assert(list_is_empty(&client->read_requests));
            assert(client->channel == c);
            send_read_reply(client, token, size);
            advance_stream_buffer(stream);
        }
    }
    else {
        write_stringz(&c->out, "R");
        write_stringz(&c->out, token);
        write_stringz(&c->out, "null");
        write_errno(&c->out, err);
        json_write_long(&c->out, 0);
        write_stream(&c->out, 0);
        json_write_boolean(&c->out, 0);
        write_stream(&c->out, 0);
        write_stream(&c->out, MARKER_EOM);
    }
}
Пример #12
0
main()

{
	DynamicList* l = list_inicialize();

	/*Aluno* Al1 = (Aluno*)malloc(sizeof(Aluno));
	Aluno* Al2 = (Aluno*)malloc(sizeof(Aluno));

	Al1->RA = 1516;
	Al1->nome = "JOAO";

	Al2->RA = 2324;
	Al2->nome = "SIBA";
	*/

	printf("\nInseriu? %s", list_add_last(l, 'a')?"sim":"não");
	printf("\nInseriu? %s", list_add_last(l, 'b')?"sim":"não");

	printf("\nFirst %c\n", list_get_first(l));
	printf("\nLast %c\n", list_get_last(l));

	printf("\nInseriu? %s", list_add_last(l, 'c')?"sim":"não");
	printf("\nInseriu? %s", list_add_last(l, 'd')?"sim":"não");
	printf("\nInseriu? %s", list_add_first(l, 'e')?"sim":"não");
	printf("\nInseriu? %s", list_add_first(l, 'f')?"sim":"não");
	printf("\nInseriu? %s", list_add_first(l, 'g')?"sim":"não");

	printf("\nFirst %c\n", list_get_first(l));
	printf("\nLast %c\n", list_get_last(l));

	list_print(l);

	printf("\nSize %d\n", list_size(l));

	list_clear(l);

	printf("\nSize %d\n", list_size(l));

	printf("\nInseriu? %s", list_add_last(l, 'c')?"sim":"não");
	printf("\nInseriu? %s", list_add_last(l, 'd')?"sim":"não");
	printf("\nInseriu? %s", list_add_first(l, 'e')?"sim":"não");
	printf("\nInseriu? %s", list_add_first(l, 'f')?"sim":"não");
	printf("\nInseriu? %s", list_add_first(l, 'g')?"sim":"não");

	list_print(l);

	list_remove_first(l);	
	list_remove_first(l);	
	list_remove_first(l);	
	
	list_print(l);
}
Пример #13
0
struct task_t *task_start(task_func_t *task_func) {
  struct task_t *task = (struct task_t *)malloc_alloc(sizeof(struct task_t));
  char *p = malloc_alloc(0x800);
  p += 0x800;
  task->sp = (uint32 *)(p); // 2k stack
  task->msg = 0;
  task->state = TASK_STATE_ACTIVE;
  list_init(&task->input_channels);
  list_init(&task->output_channels);
  task_create(&task->sp, task_func);
  list_add_last(active_tasks, task);
  print_buf("task start:");
  print_buf(" t=");
  print_ptr(task);
  print_buf(" t->sp=");
  print_ptr(task->sp);
  print_buf("\n");
  return task;
}
Пример #14
0
static void event_attach_done(void * x) {
    AttachDoneArgs * args = (AttachDoneArgs *)x;
    if (context_find_from_pid(args->pid, 0) != NULL) {
        args->done(ERR_ALREADY_ATTACHED, NULL, args->data);
    }
    else {
        Context * ctx = NULL;
        if (parent_ctx == NULL) {
            pid_t pid = taskIdSelf();
            parent_ctx = create_context(pid2id(pid, 0));
            EXT(parent_ctx)->pid = pid;
            parent_ctx->mem = parent_ctx;
            parent_ctx->mem_access |= MEM_ACCESS_INSTRUCTION;
            parent_ctx->mem_access |= MEM_ACCESS_DATA;
            parent_ctx->big_endian = big_endian_host();
            link_context(parent_ctx);
            send_context_created_event(parent_ctx);
        }
        assert(parent_ctx->ref_count > 0);
        ctx = create_context(pid2id(args->pid, EXT(parent_ctx)->pid));
        EXT(ctx)->pid = args->pid;
        EXT(ctx)->regs = (REG_SET *)loc_alloc(sizeof(REG_SET));
        ctx->mem = parent_ctx;
        ctx->big_endian = parent_ctx->big_endian;
        (ctx->parent = parent_ctx)->ref_count++;
        list_add_last(&ctx->cldl, &parent_ctx->children);
        link_context(ctx);
        trace(LOG_CONTEXT, "context: attached: ctx %#lx, id %#x", ctx, EXT(ctx)->pid);
        send_context_created_event(ctx);
        args->done(0, ctx, args->data);
        if (taskIsStopped(args->pid)) {
            struct event_info * info;
            ctx->pending_intercept = 1;
            info = event_info_alloc(EVENT_HOOK_STOP);
            if (info != NULL) {
                info->stopped_ctx.ctxId = args->pid;
                event_info_post(info);
            }
        }
    }
    loc_free(x);
}
Пример #15
0
chunk_pool_t* chunk_pool_init(int fd, int prot) {
    //log_write(DEBUG, "chunk_pool_init: start of work);
    
    chunk_pool_t* cpool = (chunk_pool_t*)calloc(1, sizeof(chunk_pool_t));
    if(!cpool) {
        //log_write(ERROR, "chunk_pool_init: cannot allocate memory);
        return NULL;
    }
    
    cpool->fd = fd;
    cpool->protection = prot;
    cpool->zero_chunks = list_init();
    cpool->free_chunks = list_init();
    cpool->hash = ht_init(DEFAULT_HASH_TABLE_SIZE, hash_fnv1a);
    cpool->loafs = (chunk_t**)calloc(1, sizeof(chunk_t*));
    *cpool->loafs = (chunk_t*)calloc(DEFAULT_ARRAY_SIZE, sizeof(chunk_t));
    cpool->loafs_count = 1;
    cpool->is_mapped = 0;
    cpool->pg_size = sysconf(_SC_PAGESIZE);
    sem_init(&cpool->semaphore, 0, 1);

    struct stat sb = {0};
    int err = fstat(fd, &sb);
    cpool->file_size = sb.st_size;

    
    int i = 0;
    for(i; i < DEFAULT_ARRAY_SIZE; i++) {
        list_add_last(cpool->free_chunks, (value_t*)&(*cpool->loafs)[i]);
    }
    
    if(!cpool->hash || !cpool->zero_chunks || !cpool->free_chunks) {
        //log_write(ERROR, "chunk_pool_init: cannot allocate memory);
        return NULL;
    }
    
    return cpool;
}
Пример #16
0
int chunk_release(chunk_t* chunk) {
    if(chunk == NULL) {
        return EINVAL;
    }
    
    int err = munmap(chunk->data, chunk->cpool->pg_size*(chunk->len));
    if(err == -1) return errno;
    
    err = ht_del_item_by_key_and_value(chunk->cpool->hash, (hkey_t)chunk->index, (hvalue_t)chunk);
    if(err) return err;
    
    chunk->ref_counter = 0;
    chunk->index = 0;
    chunk->len = 0;
    chunk->data = NULL;
    
    
    err = list_add_last(chunk->cpool->free_chunks, (value_t)chunk);
    if(err) return err;
    
    return 0;
    
}
int main(void)
{
	linked_list_t *list = (linked_list_t*)malloc(sizeof(linked_list_t));
	list_init(list);

	for (int i = 0; i < 10; i++){
		char string[100];
		sprintf(string, "Number: %d", i);
		list_add_first(list_create_node(i, string), list);
		list_add_last (list_create_node(i, string), list);
	}

	printf("Non-empty list\n");
	list_print(list);

	list_clear(list);

	printf("Empty list\n");
	list_print(list);

	list_free(list);
	free(list);
	return 0;
}
Пример #18
0
static void channel_close_listener(Channel * c) {
    LINK list;
    LINK * list_next = NULL;

    list_init(&list);
    for (list_next = file_info_ring.next; list_next != &file_info_ring; list_next = list_next->next) {
        OpenFileInfo * h = ring2file(list_next);
        if (h->inp == &c->inp) {
            trace(LOG_ALWAYS, "file handle left open by client: FS%d", h->handle);
            list_remove(&h->link_hash);
            if (h->dir != NULL) {
                closedir(h->dir);
                h->dir = NULL;
            }
            if (h->file >= 0) {
                close(h->file);
                h->file = -1;
                while (!list_is_empty(&h->link_reqs)) {
                    LINK * link = h->link_reqs.next;
                    IORequest * req = reqs2req(link);
                    list_remove(link);
                    if (h->posted_req == req) {
                        req->handle = NULL;
                    }
                    else {
                        loc_free(req->info.u.fio.bufp);
                        loc_free(req);
                    }
                }
            }
            list_add_last(&h->link_hash, &list);
        }
    }

    while (!list_is_empty(&list)) delete_open_file_info(hash2file(list.next));
}
Пример #19
0
static void event_pid_stopped(pid_t pid, int signal, int event, int syscall) {
    int stopped_by_exception = 0;
    unsigned long msg = 0;
    Context * ctx = NULL;
    Context * ctx2 = NULL;

    trace(LOG_EVENTS, "event: pid %d stopped, signal %d", pid, signal);

    ctx = context_find_from_pid(pid, 1);

    if (ctx == NULL) {
        ctx = find_pending(pid);
        if (ctx != NULL) {
            Context * prs = ctx;
            assert(prs->ref_count == 0);
            ctx = create_context(pid2id(pid, pid));
            EXT(ctx)->pid = pid;
            EXT(ctx)->regs = (REG_SET *)loc_alloc(sizeof(REG_SET));
            ctx->pending_intercept = 1;
            ctx->mem = prs;
            ctx->parent = prs;
            ctx->big_endian = prs->big_endian;
            prs->ref_count++;
            list_add_last(&ctx->cldl, &prs->children);
            link_context(prs);
            link_context(ctx);
            send_context_created_event(prs);
            send_context_created_event(ctx);
            if (EXT(prs)->attach_callback) {
                EXT(prs)->attach_callback(0, prs, EXT(prs)->attach_data);
                EXT(prs)->attach_callback = NULL;
                EXT(prs)->attach_data = NULL;
            }
        }
    }

    if (ctx == NULL) return;

    assert(!ctx->exited);
    assert(!EXT(ctx)->attach_callback);

    if (signal != SIGSTOP && signal != SIGTRAP) {
        sigset_set(&ctx->pending_signals, signal, 1);
        if (sigset_get(&ctx->sig_dont_stop, signal) == 0) {
            ctx->pending_intercept = 1;
            stopped_by_exception = 1;
        }
    }

    if (ctx->stopped) {
        send_context_changed_event(ctx);
    }
    else {
        thread_state_t state;
        unsigned int state_count;
        ContextAddress pc0 = 0;
        ContextAddress pc1 = 0;

        assert(!EXT(ctx)->regs_dirty);

        EXT(ctx)->end_of_step = 0;
        EXT(ctx)->ptrace_event = event;
        ctx->signal = signal;
        ctx->stopped_by_bp = 0;
        ctx->stopped_by_exception = stopped_by_exception;
        ctx->stopped = 1;

        if (EXT(ctx)->regs_error) {
            release_error_report(EXT(ctx)->regs_error);
            EXT(ctx)->regs_error = NULL;
        }
        else {
            pc0 = get_regs_PC(ctx);
        }

        if (thread_get_state(EXT(ctx)->pid, x86_THREAD_STATE32, EXT(ctx)->regs, &state_count) != KERN_SUCCESS) {
            assert(errno != 0);
            EXT(ctx)->regs_error = get_error_report(errno);
            trace(LOG_ALWAYS, "error: thread_get_state failed; id %s, error %d %s",
                ctx->id, errno, errno_to_str(errno));
        }
        else {
            pc1 = get_regs_PC(ctx);
        }

        if (!EXT(ctx)->syscall_enter || EXT(ctx)->regs_error || pc0 != pc1) {
            EXT(ctx)->syscall_enter = 0;
            EXT(ctx)->syscall_exit = 0;
            EXT(ctx)->syscall_id = 0;
            EXT(ctx)->syscall_pc = 0;
        }
        trace(LOG_EVENTS, "event: pid %d stopped at PC = %#lx", pid, pc1);

        if (signal == SIGTRAP && event == 0 && !syscall) {
            size_t break_size = 0;
            get_break_instruction(ctx, &break_size);
            ctx->stopped_by_bp = !EXT(ctx)->regs_error && is_breakpoint_address(ctx, pc1 - break_size);
            EXT(ctx)->end_of_step = !ctx->stopped_by_bp && EXT(ctx)->pending_step;
            if (ctx->stopped_by_bp) set_regs_PC(ctx, pc1 - break_size);
        }
        EXT(ctx)->pending_step = 0;
        send_context_stopped_event(ctx);
    }
}
Пример #20
0
error_t do_fork(fork_info_t *info)
{
	kmem_req_t req;
	struct dqdt_attr_s attr;
	struct thread_s *child_thread;
	struct task_s *child_task;
	struct page_s *page;
	uint_t cid;
	error_t err;
	sint_t order;
  
	fork_dmsg(1, "%s: cpu %d, started [%d]\n", 
		  __FUNCTION__, 
		  cpu_get_id(),
		  cpu_time_stamp());
  
	child_thread = NULL;
	child_task   = NULL;
	page         = NULL;
	cid	      = info->cpu->cluster->id;
	attr.cid      = cid;
	attr.cpu_id   = 0;
        attr.cid_exec = info->cid_exec;

	//dqdt_update_threads_number(attr.cluster->levels_tbl[0], attr.cpu->lid, 1);
	dqdt_update_threads_number(cid, attr.cpu_id, 1);

        //attr.cluster = info->current_clstr;
        attr.cid = cid;
	err = task_create(&child_task, &attr, CPU_USR_MODE);
  
        //attr.cluster = info->cpu->cluster;
        attr.cid = cid;

	if(err) goto fail_task;

	fork_dmsg(1, "%s: cpu %d, ppid %d, task @0x%x, pid %d, task @0x%x [%d]\n",
		  __FUNCTION__, 
		  cpu_get_id(), 
		  info->this_task->pid, 
		  info->this_task,
		  child_task->pid,
		  child_task,
		  cpu_time_stamp());
  
	req.type  = KMEM_PAGE;
	req.size  = ARCH_THREAD_PAGE_ORDER;
	req.flags = AF_KERNEL | AF_REMOTE;
	req.ptr   = info->cpu->cluster;
	req.ptr   = info->current_clstr;

	page = kmem_alloc(&req);

	if(page == NULL) 
		goto fail_mem;

	fork_dmsg(1, "%s: child pid will be %d on cluster %d, cpu %d [%d]\n", 
		  __FUNCTION__, 
		  child_task->pid, 
		  child_task->cpu->cluster->id, 
		  child_task->cpu->gid,
		  cpu_time_stamp());

	err = task_dup(child_task, info->this_task);
  
	if(err) goto fail_task_dup;

	signal_manager_destroy(child_task);
	signal_manager_init(child_task);
  
	fork_dmsg(1, "%s: parent task has been duplicated [%d]\n", 
		  __FUNCTION__, 
		  cpu_time_stamp());

	child_task->current_clstr = info->current_clstr;

	err = vmm_dup(&child_task->vmm, &info->this_task->vmm);

	if(err) goto fail_vmm_dup;
  
	fork_dmsg(1, "%s: parent vmm has been duplicated [%d]\n", 
		  __FUNCTION__, 
		  cpu_time_stamp());

	child_thread = (struct thread_s*) ppm_page2addr(page);

	/* Set the child page before calling thread_dup */
	child_thread->info.page = page;

	err = thread_dup(child_task,
			 child_thread,
			 info->cpu,
			 info->cpu->cluster,
			 info->this_thread);

	if(err) goto fail_thread_dup;

	/* Adjust child_thread attributes */
	if(info->flags & PT_FORK_USE_AFFINITY)
	{
		child_thread->info.attr.flags |= (info->flags & ~(PT_ATTR_LEGACY_MASK));

		if(!(info->flags & PT_ATTR_MEM_PRIO))
			child_thread->info.attr.flags &= ~(PT_ATTR_MEM_PRIO);

		if(!(info->flags & PT_ATTR_AUTO_MGRT))
			child_thread->info.attr.flags &= ~(PT_ATTR_AUTO_MGRT);

		if(!(info->flags & PT_ATTR_AUTO_NXTT))
			child_thread->info.attr.flags &= ~(PT_ATTR_AUTO_NXTT);
	}

	fork_dmsg(1, "%s: parent current thread has been duplicated, tid %x [%d]\n",
		  __FUNCTION__, 
		  child_thread, 
		  cpu_time_stamp());
	
	if(info->isPinned)
		thread_migration_disabled(child_thread);
	else
		thread_migration_enabled(child_thread);
	
	list_add_last(&child_task->th_root, &child_thread->rope);
	child_task->threads_count = 1;
	child_task->threads_nr ++;
	child_task->state = TASK_READY;

	order = bitmap_ffs2(child_task->bitmap, 0, sizeof(child_task->bitmap));

	if(order == -1) goto fail_order;

	bitmap_clear(child_task->bitmap, order);
	child_thread->info.attr.key = order;
	child_thread->info.order = order;
	child_task->next_order = order + 1;
	child_task->max_order = order;
	child_task->uid = info->this_task->uid;
	child_task->parent = info->this_task->pid;

	err = sched_register(child_thread);
  
	assert(err == 0);
    
	cpu_context_set_tid(&child_thread->info.pss, (reg_t)child_thread);
	cpu_context_set_pmm(&child_thread->info.pss, &child_task->vmm.pmm);
	cpu_context_dup_finlize(&child_thread->pws, &child_thread->info.pss);
  
	child_thread->info.retval = 0;
	child_thread->info.errno = 0;

	info->child_thread = child_thread;
	info->child_task = child_task;
	return 0;

fail_order:
fail_thread_dup:
fail_vmm_dup:
fail_task_dup:
	printk(WARNING, "WARNING: %s: destroy child thread\n", __FUNCTION__);
	req.ptr = page;
	kmem_free(&req);

fail_mem:
fail_task:
	//FIXME
	//dqdt_update_threads_number(attr.cluster->levels_tbl[0], attr.cpu->lid, -1);
	dqdt_update_threads_number(attr.cid, attr.cpu_id, -1);

	printk(WARNING, "WARNING: %s: destroy child task\n", __FUNCTION__);

	if(child_task != NULL)
		task_destroy(child_task);

	printk(WARNING, "WARNING: %s: fork err %d [%d]\n", 
	       __FUNCTION__, 
	       err, 
	       cpu_time_stamp());

	return err;
}
static PortServer * create_port_server(Channel * c, PortRedirectionInfo * redir) {
    int sock;
    struct sockaddr_in addr;
    PortAttribute * attr = redir->attrs;
#if defined(_WRS_KERNEL)
    int addrlen;
#else
    socklen_t addrlen;
#endif
    u_short port_number;
    PortServer * server = NULL;
    int is_udp = 0;           /* do we use a server UDP -or TCP- port? */

    while (attr != NULL) {
        if (strcmp(attr->name,  "Config") == 0) {
            ByteArrayInputStream buf;
            char * config;
            InputStream * inp = create_byte_array_input_stream(&buf, attr->value, strlen(attr->value));
            config = json_read_alloc_string(inp);
            if (strncasecmp(config, "udp:", strlen("udp:")) == 0) {
                is_udp = 1;
            }
            loc_free(config);
            break;
        }
        attr = attr->next;
    }
    memset((void *) &addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = (u_short) htons(redir->local_port);

    sock = -1;

    if (is_udp) sock = socket(AF_INET, SOCK_DGRAM, 0);
    else if ((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0) set_socket_options(sock); /* set socket options */

    if (sock == -1) return NULL ;

    if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
        if (redir->local_port != 0) {
            memset((void *) &addr, 0, sizeof(addr));
            addr.sin_family = AF_INET;
            addr.sin_addr.s_addr = htonl(INADDR_ANY);
            addr.sin_port = (u_short) 0;
            if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
                perror ("bind");
                goto error;
            }
        } else {
            perror("bind");
            goto error;
        }
    }

    if (!is_udp) {
        if (listen(sock, 16) != 0) goto error;
    }

    /* Get port property in case the default port could not be used or
     * the client specified a port that the system converts to a
     * dynamic port number. */
    addrlen = sizeof addr;
    if (getsockname(sock, (struct sockaddr *) &addr, &addrlen) < 0) goto error;
    port_number = (u_short) ntohs(addr.sin_port);

    server = loc_alloc_zero(sizeof(PortServer));
    server->sock = sock;
    server->is_udp = is_udp;
#if defined(SOCK_MAXADDRLEN)
    server->addr_len = SOCK_MAXADDRLEN;
#else
    server->addr_len = 0x1000;
#endif
    server->addr_buf = (struct sockaddr *)loc_alloc(server->addr_len);
    server->local_port = port_number;

    if (!server->is_udp) {
        server->accept_in_progress = 1;

        server->accreq.done = port_server_accept_done;
        server->accreq.client_data = server;
        server->accreq.type = AsyncReqAccept;
        server->accreq.u.acc.sock = sock;
        server->accreq.u.acc.addr = server->addr_buf;
        server->accreq.u.acc.addrlen = server->addr_len;
        async_req_post(&server->accreq);
        }
    else
        {
        /* For UDP, automatically connect to the port since there is no
         * connection request we can detect.
         */
        redir->auto_connect = 1;
        }

    list_add_last(&server->link, &server_list);
    channel_lock_with_msg(server->channel = c, channel_lock_svr_msg);
    snprintf (server->id, sizeof(server->id), "%" PRIu64, port_server_id++);
    return server;
    error:
    closesocket(sock);
    loc_free(server);
    return NULL ;
}
static void command_write(char * token, Channel * c) {
    char id[256];
    StreamClient * client = NULL;
    long size = 0;
    long offs = 0;
    char * data = NULL;
    int err = 0;

    json_read_string(&c->inp, id, sizeof(id));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    size = json_read_long(&c->inp);
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);

    client = find_client(id, c);
    if (client == NULL) err = errno;
    if (!err && (client->stream->access & VS_ENABLE_REMOTE_WRITE) == 0) err = ERR_UNSUPPORTED;

    {
        JsonReadBinaryState state;
        unsigned data_pos = 0;

        if (!err && !list_is_empty(&client->write_requests)) data = loc_alloc(size);

        json_read_binary_start(&state, &c->inp);
        for (;;) {
            if (data != NULL) {
                size_t rd = json_read_binary_data(&state, data + data_pos, size - offs - data_pos);
                if (rd == 0) break;
                data_pos += rd;
            }
            else {
                char buf[256];
                size_t rd = json_read_binary_data(&state, buf, sizeof(buf));
                if (rd == 0) break;
                if (!err) {
                    size_t done = 0;
                    if (virtual_stream_add_data(client->stream, buf, rd, &done, 0) < 0) err = errno;
                    assert(done <= rd);
                    offs += done;
                    if (!err && done < rd) {
                        data = loc_alloc(size - offs);
                        memcpy(data, buf + done, rd - done);
                        data_pos = rd - done;
                    }
                }
            }
        }
        json_read_binary_end(&state);
    }

    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    if (data != NULL) {
        WriteRequest * r = loc_alloc_zero(sizeof(WriteRequest));
        list_init(&r->link_client);
        r->client = client;
        r->data = data;
        r->size = size - offs;
        strncpy(r->token, token, sizeof(r->token) - 1);
        list_add_last(&r->link_client, &client->write_requests);
    }
    else {
        write_stringz(&c->out, "R");
        write_stringz(&c->out, token);
        write_errno(&c->out, err);
        write_stream(&c->out, MARKER_EOM);
    }
}
Пример #23
0
static void event_handler(void * arg) {
    struct event_info * info = (struct event_info *)arg;
    Context * current_ctx = context_find_from_pid(info->current_ctx.ctxId, 1);
    Context * stopped_ctx = context_find_from_pid(info->stopped_ctx.ctxId, 1);

    switch (info->event) {
    case EVENT_HOOK_BREAKPOINT:
        if (stopped_ctx == NULL) break;
        assert(!stopped_ctx->stopped);
        assert(!EXT(stopped_ctx)->regs_dirty);
        if (EXT(stopped_ctx)->regs_error) {
            release_error_report(EXT(stopped_ctx)->regs_error);
            EXT(stopped_ctx)->regs_error = NULL;
        }
        memcpy(EXT(stopped_ctx)->regs, &info->regs, sizeof(REG_SET));
        EXT(stopped_ctx)->event = 0;
        stopped_ctx->signal = SIGTRAP;
        stopped_ctx->stopped = 1;
        stopped_ctx->stopped_by_bp = info->bp_info_ok;
        stopped_ctx->stopped_by_exception = 0;
        assert(get_regs_PC(stopped_ctx) == info->addr);
        if (stopped_ctx->stopped_by_bp && !is_breakpoint_address(stopped_ctx, info->addr)) {
            /* Break instruction that is not planted by us */
            stopped_ctx->stopped_by_bp = 0;
            stopped_ctx->pending_intercept = 1;
        }
        EXT(stopped_ctx)->bp_info = info->bp_info;
        if (current_ctx != NULL) EXT(stopped_ctx)->bp_pid = EXT(current_ctx)->pid;
        assert(taskIsStopped(EXT(stopped_ctx)->pid));
        trace(LOG_CONTEXT, "context: stopped by breakpoint: ctx %#lx, id %#x",
                stopped_ctx, EXT(stopped_ctx)->pid);
        send_context_stopped_event(stopped_ctx);
        break;
    case EVENT_HOOK_STEP_DONE:
        if (current_ctx == NULL) break;
        assert(!current_ctx->stopped);
        assert(!EXT(current_ctx)->regs_dirty);
        if (EXT(current_ctx)->regs_error) {
            release_error_report(EXT(current_ctx)->regs_error);
            EXT(current_ctx)->regs_error = NULL;
        }
        memcpy(EXT(current_ctx)->regs, &info->regs, sizeof(REG_SET));
        EXT(current_ctx)->event = TRACE_EVENT_STEP;
        current_ctx->signal = SIGTRAP;
        current_ctx->stopped = 1;
        current_ctx->stopped_by_bp = 0;
        current_ctx->stopped_by_exception = 0;
        assert(taskIsStopped(EXT(current_ctx)->pid));
        trace(LOG_CONTEXT, "context: stopped by end of step: ctx %#lx, id %#x",
                current_ctx, EXT(current_ctx)->pid);
        send_context_stopped_event(current_ctx);
        break;
    case EVENT_HOOK_STOP:
        if (stopped_ctx == NULL) break;
        assert(!stopped_ctx->exited);
        if (stopped_ctx->stopped) break;
        if (EXT(stopped_ctx)->regs_error) {
            release_error_report(EXT(stopped_ctx)->regs_error);
            EXT(stopped_ctx)->regs_error = NULL;
        }
        if (taskRegsGet(EXT(stopped_ctx)->pid, EXT(stopped_ctx)->regs) != OK) {
            EXT(stopped_ctx)->regs_error = get_error_report(errno);
            assert(EXT(stopped_ctx)->regs_error != NULL);
        }
        EXT(stopped_ctx)->event = 0;
        stopped_ctx->signal = SIGSTOP;
        stopped_ctx->stopped = 1;
        stopped_ctx->stopped_by_bp = 0;
        stopped_ctx->stopped_by_exception = 0;
        assert(taskIsStopped(EXT(stopped_ctx)->pid));
        trace(LOG_CONTEXT, "context: stopped by sofware request: ctx %#lx, id %#x",
                stopped_ctx, EXT(stopped_ctx)->pid);
        send_context_stopped_event(stopped_ctx);
        break;
    case EVENT_HOOK_TASK_ADD:
        if (current_ctx == NULL) break;
        assert(stopped_ctx == NULL);
        stopped_ctx = create_context(pid2id((pid_t)info->stopped_ctx.ctxId, EXT(current_ctx->parent)->pid));
        EXT(stopped_ctx)->pid = (pid_t)info->stopped_ctx.ctxId;
        EXT(stopped_ctx)->regs = (REG_SET *)loc_alloc(sizeof(REG_SET));
        stopped_ctx->mem = current_ctx->mem;
        stopped_ctx->big_endian = current_ctx->mem->big_endian;
        (stopped_ctx->creator = current_ctx)->ref_count++;
        (stopped_ctx->parent = current_ctx->parent)->ref_count++;
        assert(stopped_ctx->mem == stopped_ctx->parent->mem);
        list_add_last(&stopped_ctx->cldl, &stopped_ctx->parent->children);
        link_context(stopped_ctx);
        trace(LOG_CONTEXT, "context: created: ctx %#lx, id %#x",
                stopped_ctx, EXT(stopped_ctx)->pid);
        send_context_created_event(stopped_ctx);
        break;
    default:
        assert(0);
        break;
    }
    loc_free(info);
    SPIN_LOCK_ISR_TAKE(&events_lock);
    events_cnt--;
    SPIN_LOCK_ISR_GIVE(&events_lock);
}
Пример #24
0
static void * worker_thread_handler(void * x) {
    WorkerThread * wt = x;

    for (;;) {
        AsyncReqInfo * req = wt->req;

        assert(req != NULL);
        req->error = 0;
        switch(req->type) {
        case AsyncReqRead:              /* File read */
            req->u.fio.rval = read(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqWrite:             /* File write */
            req->u.fio.rval = write(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqSeekRead:              /* File read at offset */
            req->u.fio.rval = pread(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz, req->u.fio.offset);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqSeekWrite:             /* File write at offset */
            req->u.fio.rval = pwrite(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz, req->u.fio.offset);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqRecv:              /* Socket recv */
            req->u.sio.rval = recv(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags);
            if (req->u.sio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqSend:              /* Socket send */
            req->u.sio.rval = send(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags);
            if (req->u.sio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqRecvFrom:          /* Socket recvfrom */
            req->u.sio.rval = recvfrom(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags, req->u.sio.addr, &req->u.sio.addrlen);
            if (req->u.sio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqSendTo:            /* Socket sendto */
            req->u.sio.rval = sendto(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags, req->u.sio.addr, req->u.sio.addrlen);
            if (req->u.sio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqAccept:            /* Accept socket connections */
            req->u.acc.rval = accept(req->u.acc.sock, req->u.acc.addr, req->u.acc.addr ? &req->u.acc.addrlen : NULL);
            if (req->u.acc.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqConnect:           /* Connect to socket */
            req->u.acc.rval = connect(req->u.con.sock, req->u.con.addr, req->u.con.addrlen);
            if (req->u.con.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

/* Platform dependant IO methods */
#if defined(WIN32)
#elif defined(_WRS_KERNEL)
#else
        case AsyncReqWaitpid:           /* Wait for process change */
            req->u.wpid.rval = waitpid(req->u.wpid.pid, &req->u.wpid.status, req->u.wpid.options);
            if (req->u.con.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;
#endif
        case AsyncReqSelect:
        {
            struct timeval tv;
            tv.tv_sec = (long)req->u.select.timeout.tv_sec;
            tv.tv_usec = req->u.select.timeout.tv_nsec / 1000;
            req->u.select.rval = select(req->u.select.nfds, &req->u.select.readfds,
                        &req->u.select.writefds, &req->u.select.errorfds, &tv);
            if (req->u.con.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;
        }
        case AsyncReqClose:
            req->u.fio.rval = close(req->u.fio.fd);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;
        default:
            req->error = ENOSYS;
            break;
        }
        trace(LOG_ASYNCREQ, "async_req_complete: req %p, type %d, error %d", req, req->type, req->error);
        check_error(pthread_mutex_lock(&wtlock));
        /* Post event inside lock to make sure a new worker thread is
         * not created unnecessarily */
        post_event(req->done, req);
        wt->req = NULL;
        list_add_last(&wt->wtlink, &wtlist);
        for (;;) {
            check_error(pthread_cond_wait(&wt->cond, &wtlock));
            if (wt->req != NULL) break;
        }
        check_error(pthread_mutex_unlock(&wtlock));
    }
}
Пример #25
0
void* kvfsd(void *arg)
{
	uint_t tm_now, cntr;
	struct task_s *task;
	struct thread_s *this;
	struct cpu_s *cpu;
	struct alarm_info_s info;
	struct event_s event;
	uint_t fs_type;
	error_t err;
	
	cpu_enable_all_irq(NULL);

	printk(INFO, "INFO: Starting KVFSD on CPU %d [ %d ]\n", cpu_get_id(), cpu_time_stamp());

	task    = current_task;
	fs_type = VFS_TYPES_NR;

#if CONFIG_ROOTFS_IS_EXT2
	fs_type = VFS_EXT2_TYPE;
#endif
 
#if CONFIG_ROOTFS_IS_VFAT

#if CONFIG_ROOTFS_IS_EXT2
#error More than one root fs has been selected
#endif

	fs_type = VFS_VFAT_TYPE;
#endif  /* CONFIG_ROOTFS_IS_VFAT_TYPE */
  
	err = vfs_init(__sys_blk,
		       fs_type,
		       VFS_MAX_NODE_NUMBER,
		       VFS_MAX_FILE_NUMBER,
		       &task->vfs_root);

	task->vfs_cwd = task->vfs_root;

	printk(INFO, "INFO: Virtual File System (VFS) Is Ready\n");

	sysconf_init();

	if(err == 0)
	{
		if((err = task_load_init(task)))
		{
			printk(WARNING, "WARNING: failed to load user process, err %d [%u]\n", 
			       err,
			       cpu_time_stamp());
		}
	}

#if CONFIG_DEV_VERSION
	if(err != 0)
	{
		struct thread_s *thread;

		printk(INFO, "INFO: Creating kernel level terminal\n"); 

		thread = kthread_create(task, 
					&kMiniShelld, 
					NULL, 
					current_cluster->id,
					current_cpu->lid);
		thread->task = task;
		list_add_last(&task->th_root, &thread->rope);
		err = sched_register(thread);
		assert(err == 0);
		sched_add_created(thread);
	}
#endif

	this = current_thread;
	cpu  = current_cpu;

	event_set_senderId(&event, this);
	event_set_priority(&event, E_FUNC);
	event_set_handler(&event, &kvfsd_alarm_event_handler);
  
	info.event = &event;
	cntr       = 0;

	while(1)
	{
		alarm_wait(&info, 10);
		sched_sleep(this);
		tm_now = cpu_time_stamp();
		printk(INFO, "INFO: System Current TimeStamp %u\n", tm_now);
		sync_all_pages();

		if((cntr % 4) == 0)
			dqdt_print_summary(dqdt_root);

		cntr ++;
	}
	return NULL;
}
static ChannelNP * create_channel(noPollConn * np_sock, int en_ssl, int server) {
    const int i = 1;
    ChannelNP * c;
    int sock = nopoll_conn_socket(np_sock);

    assert(np_sock >= 0);
    if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&i, sizeof(i)) < 0) {
        int error = errno;
        trace(LOG_ALWAYS, "Can't set TCP_NODELAY option on a socket: %s", errno_to_str(error));
        errno = error;
        return NULL;
    }
    if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&i, sizeof(i)) < 0) {
        int error = errno;
        trace(LOG_ALWAYS, "Can't set SO_KEEPALIVE option on a socket: %s", errno_to_str(error));
        errno = error;
        return NULL;
    }

    c = (ChannelNP *)loc_alloc_zero(sizeof *c);
#if ENABLE_Splice
    if (pipe(c->pipefd) == -1) {
        int err = errno;
        loc_free(c);
        trace(LOG_ALWAYS, "Cannot create channel pipe : %s", errno_to_str(err));
        errno = err;
        return NULL;
    }
#endif /* ENABLE_Splice */
    c->magic = CHANNEL_MAGIC;
    c->is_ssl = en_ssl;
    c->chan.inp.read = np_read_stream;
    c->chan.inp.peek = np_peek_stream;
    c->obuf = output_queue_alloc_obuf();
    c->chan.out.cur = c->obuf->buf;
    c->chan.out.end = c->obuf->buf + sizeof(c->obuf->buf);
    c->chan.out.write = np_write_stream;
    c->chan.out.write_block = np_write_block_stream;
    c->chan.out.splice_block = np_splice_block_stream;
    list_add_last(&c->chan.chanlink, &channel_root);
    shutdown_set_normal(&channel_shutdown);
    c->chan.state = ChannelStateStartWait;
    c->chan.incoming = server;
    c->chan.start_comm = start_channel;
    c->chan.check_pending = channel_check_pending;
    c->chan.message_count = channel_get_message_count;
    c->chan.lock = np_lock;
    c->chan.unlock = np_unlock;
    c->chan.is_closed = np_is_closed;
    c->chan.close = send_eof_and_close;
    ibuf_init(&c->ibuf, &c->chan.inp);
    c->ibuf.post_read = np_post_read;
    c->ibuf.wait_read = np_wait_read;
    c->ibuf.trigger_message = np_trigger_message;
    c->socket = nopoll_conn_socket(np_sock);
    c->np_socket = np_sock;
    c->lock_cnt = 1;
    c->rd_req.done = np_channel_read_done;
    c->rd_req.client_data = c;
    c->rd_req.type = AsyncReqSelect;
#if ENABLE_OutputQueue
    output_queue_ini(&c->out_queue);
#endif
    return c;
}
Пример #27
0
void test_list(void)
{
    int val[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    list me = list_init(sizeof(int));
    assert(me);
    assert(list_size(me) == 0);
    assert(list_is_empty(me));
    for (int i = 0; i < 10; i++) {
        list_add_first(me, &val[i]);
        assert(list_size(me) == i + 1);
        int get = 0;
        list_get_first(&get, me);
        assert(get == val[i]);
    }
    assert(list_size(me) == 10);
    assert(!list_is_empty(me));
    int get_arr[10] = {0};
    list_copy_to_array(get_arr, me);
    for (int i = 0; i < 10; i++) {
        int get = 0;
        list_get_at(&get, me, i);
        assert(get == val[9 - i]);
        assert(get_arr[i] == val[9 - i]);
    }
    for (int i = 0; i < 7; i++) {
        list_remove_last(me);
    }
    int trimmed[5] = {0};
    list_copy_to_array(trimmed, me);
    assert(list_size(me) == 3);
    for (int i = 0; i < 3; i++) {
        assert(10 - i == trimmed[i]);
    }
    int add = 3;
    list_add_last(me, &add);
    add = -1;
    list_add_at(me, 1, &add);
    add = -2;
    list_add_last(me, &add);
    assert(list_size(me) == 6);
    int get = 0xdeadbeef;
    list_get_first(&get, me);
    assert(get == 10);
    get = 0xdeadbeef;
    list_get_at(&get, me, 0);
    assert(get == 10);
    list_get_at(&get, me, 1);
    assert(get == -1);
    list_get_at(&get, me, 2);
    assert(get == 9);
    list_get_at(&get, me, 3);
    assert(get == 8);
    list_get_at(&get, me, 4);
    assert(get == 3);
    list_get_at(&get, me, 5);
    assert(get == -2);
    get = 0xdeadbeef;
    list_get_last(&get, me);
    assert(get == -2);
    list_remove_first(me);
    list_remove_at(me, 2);
    list_remove_last(me);
    assert(list_size(me) == 3);
    get = 345;
    list_get_first(&get, me);
    assert(get == -1);
    list_get_at(&get, me, 1);
    assert(get == 9);
    list_get_last(&get, me);
    assert(get == 3);
    int set = 12;
    list_set_first(me, &set);
    set = 13;
    list_set_at(me, 1, &set);
    set = 14;
    list_set_last(me, &set);
    int arr[3] = {0};
    list_copy_to_array(arr, me);
    assert(arr[0] == 12);
    assert(arr[1] == 13);
    assert(arr[2] == 14);
    set = -5;
    list_set_at(me, 0, &set);
    set = -6;
    list_set_at(me, 1, &set);
    set = -7;
    list_set_at(me, 2, &set);
    list_copy_to_array(arr, me);
    assert(arr[0] == -5);
    assert(arr[1] == -6);
    assert(arr[2] == -7);
    assert(list_set_at(me, 4, &set) == -EINVAL);
    assert(list_get_at(&set, me, 4) == -EINVAL);
    assert(list_remove_at(me, 4) == -EINVAL);
    assert(list_add_at(me, 5, &set) == -EINVAL);
    assert(list_set_at(me, -1, &set) == -EINVAL);
    assert(list_get_at(&set, me, -1) == -EINVAL);
    assert(list_remove_at(me, -1) == -EINVAL);
    assert(list_add_at(me, -1, &set) == -EINVAL);
    list_clear(me);
    assert(list_size(me) == 0);
    assert(list_is_empty(me));
    assert(list_remove_first(me) == -EINVAL);
    assert(list_remove_last(me) == -EINVAL);
    me = list_destroy(me);
    assert(!me);
}
Пример #28
0
static void * worker_thread_handler(void * x) {
    WorkerThread * wt = (WorkerThread *)x;

    for (;;) {
        AsyncReqInfo * req = wt->req;

        assert(req != NULL);
        req->error = 0;
        switch(req->type) {
        case AsyncReqTimer:
#if defined(_WIN32) && !defined(__CYGWIN__)
            Sleep(EVENTS_TIMER_RESOLUTION);
            events_timer_ms = GetTickCount();
#else
            {
                struct timespec timenow;
                usleep(EVENTS_TIMER_RESOLUTION * 1000);
                if (clock_gettime(CLOCK_REALTIME, &timenow) == 0) {
                    events_timer_ms = (uint32_t)(timenow.tv_nsec / 1000000 + timenow.tv_sec * 1000);
                }
            }
#endif
            break;

        case AsyncReqRead:              /* File read */
            req->u.fio.rval = read(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqWrite:             /* File write */
            req->u.fio.rval = write(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqSeekRead:          /* File read at offset */
            req->u.fio.rval = pread(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz, (off_t)req->u.fio.offset);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqSeekWrite:         /* File write at offset */
            req->u.fio.rval = pwrite(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz, (off_t)req->u.fio.offset);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqRecv:              /* Socket recv */
            req->u.sio.rval = recv(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags);
            if (req->u.sio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqSend:              /* Socket send */
            req->u.sio.rval = send(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags);
            if (req->u.sio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqRecvFrom:          /* Socket recvfrom */
            req->u.sio.rval = recvfrom(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags, req->u.sio.addr, &req->u.sio.addrlen);
            if (req->u.sio.rval == -1) {
                req->error = errno;
                trace(LOG_ASYNCREQ, "AsyncReqRecvFrom: req %p, type %d, error %d", req, req->type, req->error);
                assert(req->error);
            }
            break;

        case AsyncReqSendTo:            /* Socket sendto */
            req->u.sio.rval = sendto(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags, req->u.sio.addr, req->u.sio.addrlen);
            if (req->u.sio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqAccept:            /* Accept socket connections */
            req->u.acc.rval = accept(req->u.acc.sock, req->u.acc.addr, req->u.acc.addr ? &req->u.acc.addrlen : NULL);
            if (req->u.acc.rval == -1) {
                req->error = errno;
                trace(LOG_ASYNCREQ, "AsyncReqAccept: req %p, type %d, error %d", req, req->type, req->error);
                assert(req->error);
            }
            break;

        case AsyncReqConnect:           /* Connect to socket */
            req->u.con.rval = connect(req->u.con.sock, req->u.con.addr, req->u.con.addrlen);
            if (req->u.con.rval == -1) {
                req->error = errno;
                trace(LOG_ASYNCREQ, "AsyncReqConnect: req %p, type %d, error %d", req, req->type, req->error);
                assert(req->error);
            }
            break;

/* Platform dependant IO methods */
#if defined(_WIN32) || defined(__CYGWIN__)
        case AsyncReqConnectPipe:
            req->u.cnp.rval = ConnectNamedPipe(req->u.cnp.pipe, NULL);
            if (!req->u.cnp.rval) {
                req->error = set_win32_errno(GetLastError());
                assert(req->error);
            }
            break;
#elif defined(_WRS_KERNEL)
#else
        case AsyncReqWaitpid:           /* Wait for process change */
            req->u.wpid.rval = waitpid(req->u.wpid.pid, &req->u.wpid.status, req->u.wpid.options);
            if (req->u.wpid.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;
#endif

        case AsyncReqSelect:
            {
                struct timeval tv;
                tv.tv_sec = (long)req->u.select.timeout.tv_sec;
                tv.tv_usec = req->u.select.timeout.tv_nsec / 1000;
                req->u.select.rval = select(req->u.select.nfds, &req->u.select.readfds,
                            &req->u.select.writefds, &req->u.select.errorfds, &tv);
                if (req->u.select.rval == -1) {
                    req->error = errno;
                    assert(req->error);
                }
            }
            break;

        case AsyncReqClose:
            req->u.fio.rval = close(req->u.fio.fd);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqCloseDir:
            req->u.dio.rval = closedir((DIR *)req->u.dio.dir);
            if (req->u.dio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqOpen:
            req->u.fio.rval = open(req->u.fio.file_name, req->u.fio.flags, req->u.fio.permission);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqOpenDir:
            req->u.dio.dir = opendir(req->u.dio.path);
            if (req->u.dio.dir == NULL) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqFstat:
            memset(&req->u.fio.statbuf, 0, sizeof(req->u.fio.statbuf));
            req->u.fio.rval = fstat(req->u.fio.fd, &req->u.fio.statbuf);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
#if defined(_WIN32) || defined(__CYGWIN__)
            req->u.fio.win32_attrs = req->error || !req->u.fio.file_name ?
                INVALID_FILE_ATTRIBUTES : GetFileAttributes(req->u.fio.file_name);
#endif
            break;

        case AsyncReqStat:
            memset(&req->u.fio.statbuf, 0, sizeof(req->u.fio.statbuf));
            req->u.fio.rval = stat(req->u.fio.file_name, &req->u.fio.statbuf);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
#if defined(_WIN32) || defined(__CYGWIN__)
            req->u.fio.win32_attrs = req->error ?
                INVALID_FILE_ATTRIBUTES : GetFileAttributes(req->u.fio.file_name);
#endif
            break;

        case AsyncReqLstat:
            memset(&req->u.fio.statbuf, 0, sizeof(req->u.fio.statbuf));
            req->u.fio.rval = lstat(req->u.fio.file_name, &req->u.fio.statbuf);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
#if defined(_WIN32) || defined(__CYGWIN__)
            req->u.fio.win32_attrs = req->error ?
                INVALID_FILE_ATTRIBUTES : GetFileAttributes(req->u.fio.file_name);
#endif
            break;

        case AsyncReqSetStat:
            {
                int err = 0;
                if (req->u.fio.set_stat_flags & AsyncReqSetSize) {
                    if (truncate(req->u.fio.file_name, (off_t)req->u.fio.statbuf.st_size) < 0) err = errno;
                }
                if (req->u.fio.set_stat_flags & AsyncReqSetPermissions) {
                    if (chmod(req->u.fio.file_name, req->u.fio.statbuf.st_mode) < 0) err = errno;
                }
#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WRS_KERNEL)
#  if defined(_WIN32) || defined(__CYGWIN__)
                if (req->u.fio.win32_attrs != INVALID_FILE_ATTRIBUTES) {
                    if (SetFileAttributes(req->u.fio.file_name, req->u.fio.win32_attrs) == 0)
                        err = set_win32_errno(GetLastError());
                }
#  endif
#else
                if (req->u.fio.set_stat_flags & AsyncReqSetUidGid) {
                    if (chown(req->u.fio.file_name, req->u.fio.statbuf.st_uid, req->u.fio.statbuf.st_gid) < 0) err = errno;
                }
#endif
                if (req->u.fio.set_stat_flags & AsyncReqSetAcModTime) {
                    struct utimbuf buf;
                    buf.actime = req->u.fio.statbuf.st_atime;
                    buf.modtime = req->u.fio.statbuf.st_mtime;
                    if (utime(req->u.fio.file_name, &buf) < 0) err = errno;
                }
                req->error = err;
            }
            break;

        case AsyncReqFSetStat:
            {
                int err = 0;
                if (req->u.fio.set_stat_flags & AsyncReqSetSize) {
                    if (ftruncate(req->u.fio.fd, (off_t)req->u.fio.statbuf.st_size) < 0) err = errno;
                }
#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WRS_KERNEL)
                if (req->u.fio.set_stat_flags & AsyncReqSetPermissions) {
                    if (chmod(req->u.fio.file_name, req->u.fio.statbuf.st_mode) < 0) err = errno;
                }
#  if defined(_WIN32) || defined(__CYGWIN__)
                if (req->u.fio.win32_attrs != INVALID_FILE_ATTRIBUTES) {
                    if (SetFileAttributes(req->u.fio.file_name, req->u.fio.win32_attrs) == 0)
                        err = set_win32_errno(GetLastError());
                }
#  endif
#else
                if (req->u.fio.set_stat_flags & AsyncReqSetUidGid) {
                    if (fchown(req->u.fio.fd, req->u.fio.statbuf.st_uid, req->u.fio.statbuf.st_gid) < 0) err = errno;
                }
                if (req->u.fio.set_stat_flags & AsyncReqSetPermissions) {
                    if (fchmod(req->u.fio.fd, req->u.fio.statbuf.st_mode) < 0) err = errno;
                }
#endif
                if (req->u.fio.set_stat_flags & AsyncReqSetAcModTime) {
                    struct utimbuf buf;
                    buf.actime = req->u.fio.statbuf.st_atime;
                    buf.modtime = req->u.fio.statbuf.st_mtime;
#if defined(_WIN32) && !defined(__MINGW32__)
                    if (futime(req->u.fio.fd, &buf) < 0) err = errno;
#else
                    if (utime(req->u.fio.file_name, &buf) < 0) err = errno;
#endif
                }
                req->error = err;
            }
            break;

        case AsyncReqRemove:
            req->u.fio.rval = remove(req->u.fio.file_name);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqReadDir:
            {
                int cnt = 0;
                while (cnt < req->u.dio.max_files) {
                    char path[FILE_PATH_SIZE];
                    struct DirFileNode * file = req->u.dio.files + cnt;
                    struct dirent * e;
                    struct stat st;
                    errno = 0;
                    e = readdir((DIR *)req->u.dio.dir);
                    if (e == NULL) {
                        req->error = errno;
                        if (req->error == 0) req->u.dio.eof = 1;
                        break;
                    }
                    if (strcmp(e->d_name, ".") == 0) continue;
                    if (strcmp(e->d_name, "..") == 0) continue;
                    file->path = loc_strdup(e->d_name);
                    memset(&st, 0, sizeof(st));
                    snprintf(path, sizeof(path), "%s/%s", req->u.dio.path, e->d_name);
                    if (stat(path, &st) == 0) {
#if defined(_WIN32) || defined(__CYGWIN__)
                        file->win32_attrs =  GetFileAttributes(path);
#endif
                        file->statbuf = (struct stat *)loc_alloc(sizeof(struct stat));
                        memcpy(file->statbuf, &st, sizeof(struct stat));
                    }
                    cnt++;
                }
            }
            break;

        case AsyncReqRoots:
            {
                struct stat st;
                struct RootDevNode * newDevNode = NULL;

#if defined(_WIN32) || defined(__CYGWIN__)
                {
                    struct RootDevNode * curDevNode = NULL;
                    int disk = 0;
                    DWORD disks = GetLogicalDrives();
                    for (disk = 0; disk <= 30; disk++) {
                        if (disks & (1 << disk)) {
                            char path[32];
                            newDevNode = (struct RootDevNode *)loc_alloc_zero(sizeof(struct RootDevNode));
                            if (curDevNode == NULL) req->u.root.lst = newDevNode;
                            else curDevNode->next = newDevNode;
                            curDevNode = newDevNode;
                            snprintf(path, sizeof(path), "%c:\\", 'A' + disk);
                            newDevNode->devname = loc_strdup(path);
                            if (disk >= 2) {
                                ULARGE_INTEGER total_number_of_bytes;
                                BOOL has_size = GetDiskFreeSpaceExA(path, NULL, &total_number_of_bytes, NULL);
                                memset(&st, 0, sizeof(st));
#if defined(__CYGWIN__)
                                snprintf(path, sizeof(path), "/cygdrive/%c", 'a' + disk);
#endif
                                if (has_size && stat(path, &st) == 0) {
                                    newDevNode->win32_attrs =  GetFileAttributes(path);
                                    newDevNode->statbuf = (struct stat *)loc_alloc_zero(sizeof(struct stat));
                                    memcpy(newDevNode->statbuf, &st, sizeof(struct stat));
                                }
                            }
                        }
                    }
                }
#elif defined(_WRS_KERNEL)
                {
                    struct RootDevNode * curDevNode = NULL;
                    extern DL_LIST iosDvList;
                    DEV_HDR * dev;
                    for (dev = (DEV_HDR *)DLL_FIRST(&iosDvList); dev != NULL; dev = (DEV_HDR *)DLL_NEXT(&dev->node)) {
                        char path[FILE_PATH_SIZE];
                        if (strcmp(dev->name, "host:") == 0) {
                            /* Windows host is special case */
                            int d;
                            for (d = 'a'; d < 'z'; d++) {
                                snprintf(path, sizeof(path), "%s%c:/", dev->name, d);
                                if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) {
                                    newDevNode = (struct RootDevNode *)loc_alloc_zero(sizeof(struct RootDevNode));
                                    if (curDevNode == NULL) req->u.root.lst = newDevNode;
                                    else curDevNode->next = newDevNode;
                                    curDevNode = newDevNode;

                                    newDevNode->devname = loc_strdup(path);
                                    newDevNode->statbuf = (struct stat *)loc_alloc_zero(sizeof(struct stat));
                                    memcpy(newDevNode->statbuf, &st, sizeof(struct stat));
                                }
                            }
                        }
                        snprintf(path, sizeof(path), "%s/", dev->name);
                        if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) {
                            newDevNode = (struct RootDevNode *)loc_alloc_zero(sizeof(struct RootDevNode));
                            if (curDevNode == NULL) req->u.root.lst = newDevNode;
                            else curDevNode->next = newDevNode;
                            curDevNode = newDevNode;

                            newDevNode->devname = loc_strdup(path);
                            newDevNode->statbuf = (struct stat *)loc_alloc_zero(sizeof(struct stat));
                            memcpy(newDevNode->statbuf, &st, sizeof(struct stat));
                        }
                    }
                }
#else
                req->u.root.lst = newDevNode = (struct RootDevNode *)loc_alloc_zero(sizeof(struct RootDevNode));
                newDevNode->devname = loc_strdup("/");
                if (stat("/", &st) == 0) {
                    newDevNode->statbuf = (struct stat *)loc_alloc_zero(sizeof(struct stat));
                    memcpy(newDevNode->statbuf, &st, sizeof(struct stat));
                }
#endif
            }
            break;

        case AsyncReqUser:              /* User defined request */
            req->u.user.rval = req->u.user.func(req->u.user.data);
            if (req->u.user.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        default:
            req->error = ENOSYS;
            break;
        }
        if (req->type == AsyncReqTimer) {
            if (async_shutdown.state == SHUTDOWN_STATE_PENDING) break;
            continue;
        }
        trace(LOG_ASYNCREQ, "async_req_complete: req %p, type %d, error %d", req, req->type, req->error);
        check_error(pthread_mutex_lock(&wtlock));
        /* Post event inside lock to make sure a new worker thread is not created unnecessarily */
        post_event(req->done, req);
        wt->req = NULL;
        if (wtlist_size >= MAX_WORKER_THREADS || async_shutdown.state == SHUTDOWN_STATE_PENDING) {
            check_error(pthread_mutex_unlock(&wtlock));
            break;
        }
        list_add_last(&wt->wtlink, &wtlist);
        wtlist_size++;
        for (;;) {
            check_error(pthread_cond_wait(&wt->cond, &wtlock));
            if (wt->req != NULL) break;
        }
        check_error(pthread_mutex_unlock(&wtlock));
        if (wt->req == &shutdown_req) break;
    }
    post_event(worker_thread_exit, wt);
    return NULL;
}
Пример #29
0
int virtual_stream_write(Channel * c, char * token, char * id, size_t size, InputStream * inp) {
    char * data = NULL;
    int err = 0;
    long offs = 0;
    StreamClient * client = find_client(id, c);

    if (client == NULL) err = errno;
    if (!err && (client->stream->access & VS_ENABLE_REMOTE_WRITE) == 0) err = ERR_UNSUPPORTED;

    {
        JsonReadBinaryState state;
        size_t data_pos = 0;

        if (!err && !list_is_empty(&client->write_requests)) data = (char *)loc_alloc(size);

        json_read_binary_start(&state, inp);
        for (;;) {
            if (data != NULL) {
                size_t rd = json_read_binary_data(&state, data + data_pos, size - offs - data_pos);
                if (rd == 0) break;
                data_pos += rd;
            }
            else {
                char buf[256];
                size_t rd = json_read_binary_data(&state, buf, sizeof(buf));
                if (rd == 0) break;
                if (!err) {
                    size_t done = 0;
                    if (virtual_stream_add_data(client->stream, buf, rd, &done, 0) < 0) err = errno;
                    assert(done <= rd);
                    offs += done;
                    if (!err && done < rd) {
                        data = (char *)loc_alloc(size - offs);
                        memcpy(data, buf + done, rd - done);
                        data_pos = rd - done;
                    }
                }
            }
        }
        json_read_binary_end(&state);
    }

    if (data != NULL) {
        WriteRequest * r = (WriteRequest *)loc_alloc_zero(sizeof(WriteRequest));
        list_init(&r->link_client);
        r->client = client;
        r->data = data;
        r->size = size - offs;
        strlcpy(r->token, token, sizeof(r->token));
        list_add_last(&r->link_client, &client->write_requests);
    }
    else if (err == 0) {
        write_stringz(&c->out, "R");
        write_stringz(&c->out, token);
        write_errno(&c->out, err);
        write_stream(&c->out, MARKER_EOM);
    }

    if (err != 0) errno = err;

    return err == 0 ? 0 : -1;
}
Пример #30
0
static PortServer * create_server(Channel * c, PortAttribute * attrs) {
    int sock = -1;
    struct sockaddr_in addr;
    PortAttribute * attr = attrs;
#if defined(_WRS_KERNEL)
    int addrlen;
#else
    socklen_t addrlen;
#endif
    u_short port_number;
    PortServer * server = NULL;
    int is_udp = 0;           /* do we use a server UDP -or TCP- port? */
    char * port_config = NULL;
    int error = 0;
    int auto_connect = 0;
    uint64_t auto_connect_period = 0;
    unsigned int local_port = 0;

    while (attr != NULL) {
        if (strcmp(attr->name,  "Port") == 0) {
            ByteArrayInputStream buf;
            InputStream * inp = create_byte_array_input_stream(&buf, attr->value, strlen(attr->value));
            port_config = json_read_alloc_string(inp);
            if (strncasecmp(port_config, "udp:", strlen("udp:")) == 0) {
                is_udp = 1;
            }
        }
        else if (strcmp(attr->name, "AutoConnect") == 0) {
            ByteArrayInputStream buf;
            InputStream * inp = create_byte_array_input_stream(&buf, attr->value, strlen(attr->value));
            auto_connect = json_read_boolean(inp);
        }
        else if (strcmp(attr->name, "AutoConnectPeriod") == 0) {
            ByteArrayInputStream buf;
            InputStream * inp = create_byte_array_input_stream(&buf, attr->value, strlen(attr->value));
            auto_connect_period = json_read_ulong(inp);
        }
        else if (strcmp(attr->name, "LocalPort") == 0) {
            ByteArrayInputStream buf;
            InputStream * inp = create_byte_array_input_stream(&buf, attr->value, strlen(attr->value));
            local_port = (unsigned int) json_read_uint64(inp);
        }
        attr = attr->next;
    }
    if (port_config == NULL) {
        error = set_errno(ERR_OTHER, "No port configuration is specified");
    }
    if (error == 0) {
        loc_free(port_config);
        memset((void *) &addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = htonl(INADDR_ANY);
        addr.sin_port = (u_short) htons(local_port);

        if (is_udp) sock = socket(AF_INET, SOCK_DGRAM, 0);
        else if ((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0) set_socket_options(sock); /* set socket options */

        if (sock == -1) error = errno;
    }

    if (error == 0) {
        if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
            error = errno;
        }
    }

    if (error == 0 && !is_udp) {
        if (listen(sock, 16) != 0) error = errno;
    }

    if (error == 0) {
        /* Get port property in case the default port could not be used or
         * the client specified a port that the system converts to a
         * dynamic port number. */
        addrlen = sizeof addr;
        if (getsockname(sock, (struct sockaddr *) &addr, &addrlen) < 0) error = errno;
    }

    if (error == 0) {
        port_number = (u_short) ntohs(addr.sin_port);

        server = (PortServer *)loc_alloc_zero(sizeof(PortServer));
        server->sock = sock;
        server->is_udp = is_udp;
#if defined(SOCK_MAXADDRLEN)
        server->addr_len = SOCK_MAXADDRLEN;
#else
        server->addr_len = 0x1000;
#endif
        server->addr_buf = (struct sockaddr *)loc_alloc(server->addr_len);
        server->local_port = port_number;

        if (!server->is_udp) {
            server->accept_in_progress = 1;
            server->auto_connect = auto_connect;

            server->accreq.done = port_server_accept_done;
            server->accreq.client_data = server;
            server->accreq.type = AsyncReqAccept;
            server->accreq.u.acc.sock = sock;
            server->accreq.u.acc.addr = server->addr_buf;
            server->accreq.u.acc.addrlen = server->addr_len;
            async_req_post(&server->accreq);
            }
        else
            {
            /* For UDP, automatically connect to the port since there is no
             * connection request we can detect.
             */
            server->auto_connect = 1;
            }
        server->auto_connect_period = auto_connect_period;

        list_add_last(&server->link, &server_list);
        channel_lock_with_msg(server->channel = c, channel_lock_svr_msg);
        snprintf (server->id, sizeof(server->id), "PS%" PRIu64, port_server_id++);
        server->attrs = attrs;
    }
    if (error == 0) return server;
    else {
        if (sock != -1) closesocket(sock);
        loc_free(server);
        return NULL ;
    }
}