void sangoma_worker_loop(int proc_no) { struct sngtc_request req; int rc; close(sangoma_pipe[WRITE_END]); for (;;) { rc = 0; LM_DBG("reading from pipe\n"); if (read(sangoma_pipe[READ_END], &req, sizeof(req)) < 0) { LM_ERR("failed to read from pipe (%d - %s)\n", errno, strerror(errno)); continue; } switch (req.type) { case REQ_CREATE_SESSION: LM_DBG("CREATE request\n"); if (sngtc_create_transcoding_session(&req.sng_req, req.sng_reply, 0) != 0) { LM_ERR("failed to create sng transcoding session\n"); sngtc_print_request(L_ERR, req.sng_req); rc = 1; } break; case REQ_FREE_SESSION: LM_DBG("FREE request\n"); sngtc_print_reply(L_DBG, req.sng_reply); if (sngtc_free_transcoding_session(req.sng_reply) != 0) { LM_ERR("failed to free sng transcoding session\n"); sngtc_print_reply(L_ERR, req.sng_reply); rc = 1; } break; default: LM_ERR("dropping invalid sangoma request: %d\n", req.type); rc = 1; } if (write(req.response_fd, &rc, sizeof(rc)) < 0) LM_ERR("failed to write in response pipe fd %d (%d: %s)\n", req.response_fd, errno, strerror(errno)); } }
/** * create_transcoding_session - creates a new Sangoma transcoding session and * adds it to the current dialog's list of ongoing transcoding sessions * * @info : output parameter, holds a list with all tc sessions on the card */ static struct sngtc_codec_reply *create_transcoding_session( struct sngtc_codec_request *request, struct sngtc_info *info) { struct sngtc_codec_reply *reply; struct sngtc_session_list *session; struct sngtc_request req; int rc; session = shm_malloc(sizeof(*session) + sizeof(*reply)); if (!session) { LM_ERR("no more shm mem\n"); return NULL; } reply = (struct sngtc_codec_reply *)(session + 1); session->next = NULL; session->reply = reply; LM_DBG("creating sng transcoding session\n"); req.type = REQ_CREATE_SESSION; req.response_fd = udp_receiver_pipes[pipe_index + WRITE_END]; req.sng_req = *request; req.sng_reply = reply; if (write(sangoma_pipe[WRITE_END], &req, sizeof(req)) < 0) { LM_ERR("failed to write on sangoma pipe fd %d (%d: %s)\n", sangoma_pipe[WRITE_END], errno, strerror(errno)); goto out_free; } if (read(udp_receiver_pipes[pipe_index + READ_END], &rc, sizeof(rc)) < 0) { LM_ERR("failed to read sangoma worker reply on pipe fd %d (%d: %s)\n", udp_receiver_pipes[pipe_index + READ_END], errno, strerror(errno)); goto out_free; } if (rc != 0) { LM_ERR("failed to create sangoma transcoding session\n"); goto out_free; } LM_DBG("created new transcoding session\n"); sngtc_print_reply(L_DBG, reply); if (!info->sessions) info->sessions = info->last_session = session; else { info->last_session->next = session; info->last_session = session; } return reply; out_free: free_transcoding_sessions(info->sessions); shm_free(session); return NULL; }
void free_transcoding_sessions(struct sngtc_session_list *first) { struct sngtc_session_list *session, *aux; struct sngtc_request req; int rc; req.type = REQ_FREE_SESSION; req.response_fd = udp_receiver_pipes[pipe_index + WRITE_END]; for (session = first; session; ) { LM_DBG("freeing transcoding session %p\n", session->reply); sngtc_print_reply(L_DBG, session->reply); req.sng_reply = session->reply; if (write(sangoma_pipe[WRITE_END], &req, sizeof(req)) < 0) { LM_ERR("failed to write on sangoma pipe fd %d (%d: %s)\n", sangoma_pipe[WRITE_END], errno, strerror(errno)); goto free_mem; } if (read(udp_receiver_pipes[pipe_index + READ_END], &rc, sizeof(rc)) < 0) { LM_ERR("failed to read sangoma worker reply on pipe fd %d (%d: %s)\n", udp_receiver_pipes[pipe_index + READ_END], errno, strerror(errno)); goto free_mem; } if (rc != 0) { LM_ERR("failed to free transcoding session\n"); sngtc_print_reply(L_ERR, session->reply); } LM_DBG("successfully freed transcoding session\n"); free_mem: aux = session; session = session->next; shm_free(aux); } }