void destroy_task(task_t* task) { Deprecated(); if (task == first_responder_task) { resign_first_responder(); } //close all pipes this process has opened for (int i = 0; i < FD_MAX; i++) { fd_entry entry = task->fd_table[i]; if (fd_empty(entry)) continue; if (entry.type == PIPE_TYPE) { pipe_t* pipe = (pipe_t*)entry.payload; pipe_close(pipe->fd); } } //remove task from queues and active list unlist_task(task); //printf_info("%s[%d] destroyed.", task->name, task->id); //free task's page directory free_directory(task->page_dir); array_m_destroy(task->child_tasks); std_stream_destroy(task); kfree(task->name); kfree(task); }
uint32_t read(int fd, void* buf, uint32_t count) { if (!tasking_installed()) { return -1; } if (!count) { return 0; } unsigned char* chbuf = buf; memset(chbuf, 0, count); //find fd_entry corresponding to this fd task_t* current = task_with_pid(getpid()); fd_entry ent = current->fd_table[fd]; if (fd_empty(ent)) { //errno = EBADF; return -1; } //what type of file descriptor is this? //dispatch appropriately switch (ent.type) { case STD_TYPE: return std_read(current, fd, buf, count); case FILE_TYPE: return fread(buf, sizeof(char), count, (FILE*)ent.payload); case PIPE_TYPE: default: return pipe_read(fd, buf, count); } return -1; }
int close(int fd) { task_t* curr = task_with_pid(getpid()); fd_entry ent = curr->fd_table[fd]; if (fd_empty(ent)) { return -1; } int ret = -1; switch (ent.type) { case STD_TYPE: ret = -1; break; case FILE_TYPE: fclose((FILE*)ent.payload); ret = 0; break; case PIPE_TYPE: default: ret = pipe_close(fd); break; } fd_remove(curr, fd); return ret; }
int fd_add(task_t* task, fd_entry entry) { //go through task's file descriptor table, looking for an empty slot for (int i = 0; i < FD_MAX; i++) { if (fd_empty(task->fd_table[i])) { //found an empty slot! task->fd_table[i] = entry; return i; } } ASSERT(0, "PID %d ran out of file descriptors!", task->id); return -1; }
void server(int argc, char** argv) { char* endptr; unsigned long const max_slaves = strtoul(argv[2], &endptr, 10); if ( *endptr != '\0') { perror("server: strtoul"); exit(1); } struct addrinfo hints, *servinfo_udp, *p_udp; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; int rv; if ( (rv = getaddrinfo("255.255.255.255", PORT, &hints, &servinfo_udp)) != 0 ) { fprintf(stderr, "server: getaddrinfo %s\n", gai_strerror(rv)); exit(1); } int sockfd_udp; for (p_udp = servinfo_udp; p_udp != NULL; p_udp = p_udp->ai_next) { if ( (sockfd_udp = socket(p_udp->ai_family, p_udp->ai_socktype, p_udp->ai_protocol)) == -1 ) { perror("server: socket"); continue; } set_socket_reuse(sockfd_udp); set_socket_broadcast(sockfd_udp); print_ip(p_udp); break; } if (p_udp == NULL) { fprintf(stderr, "server: failed to create socket\n"); exit(1); } struct addrinfo *p, *servinfo; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; if ( (rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) == -1) { fprintf(stderr, "server: getaddrinfo: %s\n", gai_strerror(rv)); exit(1); } int sockfd; for (p = servinfo; p != NULL; p = p->ai_next) { if ( (sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { perror("server: socket"); continue; } set_socket_reuse(sockfd); set_socket_keep_alive(sockfd); if ( bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { perror("server: bind"); close(sockfd); continue; } print_ip(p); break; } if (p == NULL) { fprintf(stderr, "server: failed to bind\n"); exit(1); } freeaddrinfo(servinfo); servinfo = NULL; printf("server: bind completed\n"); if ( listen(sockfd, LISTEN_BACKLOG) == -1) { perror("server: listen"); exit(1); } printf("server: listen completed\n"); if ( sendto(sockfd_udp, MSG_BOSS, strlen(MSG_BOSS)+1, 0, p_udp->ai_addr, p_udp->ai_addrlen) == -1) { perror("server: sendto"); exit(1); } freeaddrinfo(servinfo_udp); servinfo_udp = NULL; printf("server: sended broadcast '%s'\n", MSG_BOSS); int* sockfds2 = calloc(max_slaves, sizeof(*sockfds2)); struct Data* jobs = calloc(max_slaves, sizeof(*jobs)); struct sockaddr_storage their_addr; socklen_t their_size = 0; for (unsigned long i = 0; i < max_slaves; ++i) { jobs[i].left = LEFT + i*(RIGHT-LEFT)/max_slaves; jobs[i].right = LEFT + (i+1)*(RIGHT-LEFT)/max_slaves; jobs[i].sum = 0; jobs[i].intervals = NUM_OF_INTERVALS/max_slaves; if ( (sockfds2[i] = accept(sockfd, (struct sockaddr*)&their_addr, &their_size)) == -1) { perror("server: accept"); exit(1); } printf("server: accept completed\n"); if ( send(sockfds2[i], &jobs[i], sizeof(jobs[i]), 0) == -1) { perror("server: send"); exit(1); } printf ("server: Sended (%lg, %lg, %li)!\n", jobs[i].left, jobs[i].right, jobs[i].intervals); } fd_set not_readen; fd_set to_check; FD_ZERO(¬_readen); FD_ZERO(&to_check); int max_fd = 0; for (unsigned long i = 0; i < max_slaves; ++i) { FD_SET(sockfds2[i], ¬_readen); FD_SET(sockfds2[i], &to_check); if (sockfds2[i] > max_fd) { max_fd = sockfds2[i]; } } while ( !fd_empty(&to_check, max_fd) ) { if ( select(max_fd+1, &to_check, NULL, NULL, NULL) == -1) { perror("server: select"); exit(1); } for (unsigned long i = 0; i < max_slaves; ++i) { receive_msg(i, sockfds2, &to_check, ¬_readen, jobs); } to_check = not_readen; } free(sockfds2); free(jobs); T sum = 0.0; for (unsigned long i = 0; i < max_slaves; ++i) { sum += jobs[i].sum; } printf("server: Integral == %lg\n", sum); }