static bool fifo_open(struct fifo_data *fd, GError **error) { if (!fifo_check(fd, error)) return false; fd->input = open_cloexec(fd->path, O_RDONLY|O_NONBLOCK, 0); if (fd->input < 0) { g_set_error(error, fifo_output_quark(), errno, "Could not open FIFO \"%s\" for reading: %s", fd->path, strerror(errno)); fifo_close(fd); return false; } fd->output = open_cloexec(fd->path, O_WRONLY|O_NONBLOCK, 0); if (fd->output < 0) { g_set_error(error, fifo_output_quark(), errno, "Could not open FIFO \"%s\" for writing: %s", fd->path, strerror(errno)); fifo_close(fd); return false; } return true; }
/* free all resources, close all threads */ int bsreader_close(void) { int ret = 0; lock_all(); //TODO, possible release if (!G_ready) { printf("has not opened, cannot close\n"); return -1; } if (cancel_working_thread() < 0) { perror("pthread_cancel bsreader main"); return -1; } else { DEBUG_PRINT("main working thread canceled \n"); } fifo_close(myFIFO[0]); fifo_close(myFIFO[1]); fifo_close(myFIFO[2]); fifo_close(myFIFO[3]); if (G_bsreader_init_data.cavlc_possible) { destroy_cavlc(); } G_ready = 0; unlock_all(); pthread_mutex_destroy(&G_all_mutex); return ret; }
/* Closes the file descriptor and writes EOF to it.*/ int fd_close(int fd) { if (fd != -1 && files[fd].used) { if(files[fd].used == 0) { fifo_close(files[fd].data); } files[fd].used--; } else if (fd != -1){ if(files[fd].used == 0) { fifo_close(files[fd].data); } } // TODO: Make the remaining clears }
int child_process (void) { int fd; char buf [100]; /* Setup a signal handler for SIGINT */ signal (SIGINT, int_proc); signal (SIGTERM, int_proc); if (verbose) printf ("child start\n"); fd = fifo_open (FILENAME, 0); if (fd == -1) return EXIT_FAILURE; while (!stop) { memset (buf, 0, 100); fifo_read (fd, buf, 100); printf ("read: >%s<\n", buf); fflush (stdout); } fifo_close (fd); if (verbose) printf ("child done\n"); return EXIT_SUCCESS; }
/****************************************************************************** Description.: stops the execution of the worker thread Input Value.: - Return Value: 0 ******************************************************************************/ int input_stop(int id) { DBG("will cancel input thread\n"); pthread_cancel(worker); fifo_close(); return 0; }
static void fifo_output_finish(void *data) { struct fifo_data *fd = (struct fifo_data *)data; fifo_close(fd); fifo_data_free(fd); }
static PyObject* fifoClose(PyObject* self, PyObject* arg) { unsigned int fifo_id ; if(!PyArg_ParseTuple(arg, "l", &fifo_id)) return NULL; fifo_close(fifo_id); return Py_BuildValue("l", 1) ; }
void fifo_destroy() { char *path; fifo_close (); path = g_build_filename (g_get_home_dir (), ".quark", FIFO_NAME, NULL); unlink (path); g_free (path); }
int tmpfs_fifo_close(void *v) { struct vop_close_args /* { struct vnode *a_vp; int a_fflag; kauth_cred_t a_cred; } */ *ap = v; struct vnode *vp = ap->a_vp; tmpfs_update(vp, NULL, NULL, 0); return (fifo_close(v)); }
/* * Close wrapper for fifo's. * * Update the times on the inode then do device close. */ int ufsfifo_close(void *v) { struct vop_close_args *ap = v; struct vnode *vp = ap->a_vp; struct inode *ip = VTOI(vp); if (ap->a_vp->v_usecount > 1) { struct timeval tv; getmicrotime(&tv); ITIMES(ip, &tv, &tv); } return (fifo_close(ap)); }
static gboolean fifo_read (GIOChannel *chan, GIOCondition cond, gpointer data) { char *command; gsize term; GError *err; gboolean ret; g_static_mutex_lock (&main_fifo_mutex); err = NULL; if (cond & G_IO_IN) { while (g_io_channel_read_line (chan, &command, NULL, &term, &err) == G_IO_STATUS_NORMAL) { command[term] = '\0'; fifo_execute (command); g_free (command); } if (err) { g_warning ("error reading fifo: %s", err->message); g_error_free (err); } } if (cond & G_IO_HUP || cond & G_IO_ERR) { fifo_close (); if (!fifo_open ()) { g_critical ("failed to reopen fifo"); main_quit (); } ret = FALSE; /* remove me from the watch */ } else ret = TRUE; g_static_mutex_unlock (&main_fifo_mutex); return ret; }
int main(int argc, char *argv[]) { enum { MAX_RETRIES = 100 }; enum { SLEEP_US = 1000 }; bool attach = false; _xcc_status cc; bool client = false; int count; int count_read; int count_written; bool dif = false; double dloop; double dms; double dsec; int err; bool exec = false; int ferr; bool fin = false; MS_Mon_Process_Info_Type info; MS_Mon_Process_Info_Type *infop; int inx; int inx2; int inx3; short len; short lerr; short lerr2; int loop = 10; int max; int nid; pid_t pid; int sargc; ssize_t size; int snid; int spid; bool startup = false; xzsys_ddl_smsg_def *sys_msgp = (xzsys_ddl_smsg_def *) recv_buffer; int sys_msg; int sys_msg_count; bool verbose = false; TAD zargs[] = { { "-attach", TA_Bool, TA_NOMAX, &attach }, { "-client", TA_Bool, TA_NOMAX, &client }, { "-dif", TA_Bool, TA_NOMAX, &dif }, { "-exec", TA_Bool, TA_NOMAX, &exec }, { "-loop", TA_Int, TA_NOMAX, &loop }, { "-maxsp", TA_Int, TA_NOMAX, &maxsp }, { "-server", TA_Ign, TA_NOMAX, NULL }, { "-startup", TA_Bool, TA_NOMAX, &startup }, { "-trace", TA_Bool, TA_NOMAX, &trace }, { "-v", TA_Bool, TA_NOMAX, &verbose }, { "-verbose", TA_Ign, TA_NOMAX, NULL }, { "", TA_End, TA_NOMAX, NULL } }; arg_proc_args(zargs, false, argc, argv); sprintf(fifo1, "%s-%s", FIFO1, getenv("USER")); sprintf(fifo2, "%s-%s", FIFO2, getenv("USER")); if (trace) msg_init_trace(); if (exec) return 0; if (startup) { err = fifo_open(fifo1, O_WRONLY); assert(err != -1); ffds[1] = err; err = fifo_open(fifo2, O_RDONLY); assert(err != -1); ffds[0] = err; if (trace) trace_printf("cli: writing fifo\n"); size = write(ffds[1], recv_buffer, 1); if (trace) trace_printf("cli: fifo write, size=%d\n", (int) size); assert(size == 1); if (trace) trace_printf("cli: fifo written\n"); close(ffds[1]); return 0; } if (attach) ferr = file_init_attach(&argc, &argv, false, NULL); else ferr = file_init(&argc, &argv); TEST_CHK_FEOK(ferr); util_test_start(client); ferr = msg_mon_process_startup(true); // system messages util_check("msg_mon_process_startup", ferr); ferr = msg_mon_get_my_process_name(procname, BUFSIZ); util_check("msg_mon_get_my_process_name", ferr); ferr = msg_mon_get_process_info(procname, &nid, &pid); TEST_CHK_FEOK(ferr); if (trace) trace_printf("proc=%s, nid=%d, pid=%d\n", procname, nid, pid); dloop = (double) loop; for (inx = 0; inx < T_MAX; inx++) t_elapsed[inx] = 0.0; if (client) { printf("loop=%d, maxsp=%d\n", loop, maxsp); sargc = argc; assert(sargc < MAX_ARGS); for (inx2 = 0; inx2 < argc; inx2++) { if (strcmp(argv[inx2], "-client") == 0) sargv[inx2] = (char *) "-server"; else sargv[inx2] = argv[inx2]; if (strcmp(argv[inx2], "-attach") == 0) sargv[inx2] = (char *) "-server"; } sargv[argc] = NULL; sprintf(sprog, "%s/%s", getenv("PWD"), argv[0]); time_start(T_TOTAL); for (inx = 0; inx < loop; inx += maxsp) { if (dif) snid = -1; else snid = nid; max = loop - inx; if (max > maxsp) max = maxsp; for (inx2 = 0; inx2 < max; inx2++) sname[inx2][0] = 0; // mon picks name if (trace) trace_printf("cli: newproc, inx=%d\n", inx); time_start(T_NEWPROC); for (inx2 = 0; inx2 < max; inx2++) { ferr = msg_mon_start_process(sprog, // prog sname[inx2], // name sname[inx2], // ret_name sargc, // argc sargv, // argv TPT_REF2(sphandle,inx2),// phandle false, // open &soid[inx2], // oid MS_ProcessType_Generic, // type 0, // priority false, // debug false, // backup &snid, // nid &spid, // pid NULL, // infile NULL); // outfile TEST_CHK_FEOK(ferr); } time_stop(T_NEWPROC); time_elapsed(T_NEWPROC); // wait here until processes are 'up' // so that open timing is correct inx3 = 0; for (inx2 = 0; inx2 < max; inx2++) { ferr = msg_mon_get_process_info_detail(sname[inx2], &info); TEST_CHK_FEOK(ferr); if (info.state != MS_Mon_State_Up) { inx3++; if (inx3 > MAX_RETRIES) { printf("process %s did not enter 'UP' state\n", sname[inx2]); assert(inx3 < MAX_RETRIES); } usleep(SLEEP_US); inx2--; continue; } else inx3 = 0; } if (trace) trace_printf("cli: open, inx=%d\n", inx); time_start(T_OPEN); for (inx2 = 0; inx2 < max; inx2++) { if (trace) trace_printf("cli: opening inx=%d, name=%s\n", inx, sname[inx2]); len = (short) strlen(sname[inx2]); ferr = BFILE_OPEN_(sname[inx2], len, &sfilenum[inx2], 0, 0, 0, 0, 0, 0, 0); if (trace) trace_printf("cli: open, inx=%d, name=%s, ferr=%d\n", inx, sname[inx2], ferr); TEST_CHK_FEOK(ferr); } time_stop(T_OPEN); time_elapsed(T_OPEN); if (trace) trace_printf("cli: procinfo, inx=%d\n", inx); time_start(T_PROCINFO); for (inx2 = 0; inx2 < max; inx2++) { ferr = msg_mon_get_process_info_detail(sname[inx2], &info); TEST_CHK_FEOK(ferr); } time_stop(T_PROCINFO); time_elapsed(T_PROCINFO); if (trace) trace_printf("cli: procinfo-type, inx=%d\n", inx); time_start(T_PROCINFO_TYPE); ferr = msg_mon_get_process_info_type(MS_ProcessType_Generic, &count, MAX_SRV, infotype); TEST_CHK_FEOK(ferr); time_stop(T_PROCINFO_TYPE); time_elapsed(T_PROCINFO_TYPE); if (verbose) { for (inx2 = 0; inx2 < count; inx2++) { infop = &infotype[inx2]; char s_em = infop->event_messages ? 'E' : '-'; char s_sm = infop->system_messages ? 'S' : '-'; char s_pr = infop->pending_replication ? 'R' : '-'; char s_pd = infop->pending_delete ? 'D' : '-'; char s_s = infop->state == MS_Mon_State_Up ? 'A' : 'U'; char s_o = infop->opened ? 'O' : '-'; char s_p = infop->paired ? 'P' : infop->backup ? 'B' : '-'; printf("%3.3d,%8.8d %3.3d %d %c%c%c%c%c%c%c %-11s %-11s %-15s\n", infop->nid, infop->pid, infop->priority, infop->state, s_em, s_sm, s_pr, s_pd, s_s, s_o, s_p, infop->process_name, infop->parent_name, infop->program); } } if (trace) trace_printf("cli: close, inx=%d\n", inx); time_start(T_CLOSE); for (inx2 = 0; inx2 < max; inx2++) { ferr = BFILE_CLOSE_(sfilenum[inx2]); TEST_CHK_FEOK(ferr); } time_stop(T_CLOSE); time_elapsed(T_CLOSE); // re-open/close for (inx2 = 0; inx2 < max; inx2++) { if (trace) trace_printf("cli: re-opening inx=%d, name=%s\n", inx, sname[inx2]); len = (short) strlen(sname[inx2]); ferr = BFILE_OPEN_(sname[inx2], len, &sfilenum[inx2], 0, 0, 0, 0, 0, 0, 0); TEST_CHK_FEOK(ferr); } if (trace) trace_printf("cli: re-close, inx=%d\n", inx); for (inx2 = 0; inx2 < max; inx2++) { ferr = BFILE_CLOSE_(sfilenum[inx2]); TEST_CHK_FEOK(ferr); } if (trace) trace_printf("cli: newproc-forkexec, inx=%d\n", inx); sargc = 2; sargv[0] = argv[0]; sargv[1] = (char *) "-exec"; if (trace) sargv[sargc++] = (char *) "-trace"; sargv[sargc] = NULL; time_start(T_FORKEXEC); for (inx2 = 0; inx2 < max; inx2++) { pid = fork(); assert(pid >= 0); if (pid == 0) { // child err = execv(sprog, sargv); assert(err == 0); } } time_stop(T_FORKEXEC); time_elapsed(T_FORKEXEC); if (trace) trace_printf("cli: newproc-forkexec-su, inx=%d\n", inx); sargc = 2; sargv[0] = argv[0]; sargv[1] = (char *) "-startup"; if (trace) sargv[sargc++] = (char *) "-trace"; sargv[sargc] = NULL; time_start(T_FORKEXEC_SU); for (inx2 = 0; inx2 < max; inx2++) { fifo_create(fifo1, fifo2); pid = fork(); assert(pid >= 0); if (pid > 0) { // parent err = fifo_open(fifo1, O_RDONLY); assert(err != -1); ffds[0] = err; err = fifo_open(fifo2, O_WRONLY); assert(err != -1); ffds[1] = err; if (trace) trace_printf("cli: reading fifo, inx=%d\n", inx2); size = ::read(ffds[0], recv_buffer, 1); if (trace) trace_printf("cli: fifo read, size=%d\n", (int) size); assert(size == 1); if (trace) trace_printf("cli: fifo read, inx=%d\n", inx2); ::read(ffds[0], recv_buffer, 1); err = fifo_close(ffds[0]); assert(err == 0); err = fifo_close(ffds[1]); assert(err == 0); fifo_destroy(fifo1, fifo1); } else { // child err = execv(sprog, sargv); assert(err == 0); } } fifo_destroy(fifo2, fifo2); time_stop(T_FORKEXEC_SU); time_elapsed(T_FORKEXEC_SU); } } else { sys_msg_count = 0; time_start(T_TOTAL); ferr = BFILE_OPEN_((char *) "$RECEIVE", 8, &filenumr, 0, 0, 0, 1, 0); // sys msgs TEST_CHK_FEOK(ferr); for (inx = 0; !fin; inx++) { if (trace) trace_printf("srv: readupdate, inx=%d\n", inx); cc = BREADUPDATEX(filenumr, recv_buffer, 4, &count_read, 0); sys_msg = _xstatus_ne(cc); if (trace && sys_msg) trace_printf("srv: rcvd sys msg=%d\n", sys_msgp->u_z_msg.z_msgnumber[0]); if (sys_msg) { sys_msg_count++; inx--; } lerr2 = BFILE_GETINFO_(filenumr, &lerr); TEST_CHK_FEIGNORE(lerr2); if (trace) trace_printf("srv: reply, inx=%d\n", inx); cc = BREPLYX(recv_buffer, (unsigned short) 0, &count_written, 0, XZFIL_ERR_OK); TEST_CHK_CCEQ(cc); if (sys_msg_count >= 4) fin = true; } } time_stop(T_TOTAL); time_elapsed(T_TOTAL); if (client) { dsec = time_sec(T_TOTAL); dms = dsec * 1000.0; printf("elapsed=%f\n", dms); printf("open/close/newprocess/processinfo/forkexec=%d\n", loop); dsec = time_sec(T_OPEN); dms = dsec * 1000.0; printf("open : total-time=%f ms, time/loop=%f ms, ops/sec=%f\n", dms, dms / dloop, dloop / dsec); dsec = time_sec(T_CLOSE); dms = dsec * 1000.0; printf("close : total-time=%f ms, time/loop=%f ms, ops/sec=%f\n", dms, dms / dloop, dloop / dsec); dsec = time_sec(T_PROCINFO); dms = dsec * 1000.0; printf("procinfo : total-time=%f ms, time/loop=%f ms, ops/sec=%f\n", dms, dms / dloop, dloop / dsec); dsec = time_sec(T_PROCINFO_TYPE); dms = dsec * 1000.0; printf("procinfo-type : total-time=%f ms, time/loop=%f ms, ops/sec=%f\n", dms, dms / dloop, dloop / dsec); dsec = time_sec(T_NEWPROC); dms = dsec * 1000.0; printf("newproc : total-time=%f ms, time/loop=%f ms, ops/sec=%f\n", dms, dms / dloop, dloop / dsec); dsec = time_sec(T_FORKEXEC); dms = dsec * 1000.0; printf("forkexec : total-time=%f ms, time/loop=%f ms, ops/sec=%f\n", dms, dms / dloop, dloop / dsec); dsec = time_sec(T_FORKEXEC_SU); dms = dsec * 1000.0; printf("forkexec-startup: total-time=%f ms, time/loop=%f ms, ops/sec=%f\n", dms, dms / dloop, dloop / dsec); } ferr = msg_mon_process_shutdown(); TEST_CHK_FEOK(ferr); util_test_finish(client); return 0; }
/* * Note: This routine is single threaded * Protected by FIFOOPEN flag (i.e. flk_lock is not held) * Upon successful completion, the original fifo is unlocked * and FIFOOPEN is cleared for the original vpp. * The new fifo returned has FIFOOPEN set. */ static int fifo_connld(struct vnode **vpp, int flag, cred_t *crp) { struct vnode *vp1; struct vnode *vp2; struct fifonode *oldfnp; struct fifonode *fn_dest; int error; struct file *filep; struct fifolock *fn_lock; cred_t *c; /* * Get two vnodes that will represent the pipe ends for the new pipe. */ makepipe(&vp1, &vp2); /* * Allocate a file descriptor and file pointer for one of the pipe * ends. The file descriptor will be used to send that pipe end to * the process on the other end of this stream. Note that we get * the file structure only, there is no file list entry allocated. */ if (error = falloc(vp1, FWRITE|FREAD, &filep, NULL)) { VN_RELE(vp1); VN_RELE(vp2); return (error); } mutex_exit(&filep->f_tlock); oldfnp = VTOF(*vpp); fn_lock = oldfnp->fn_lock; fn_dest = oldfnp->fn_dest; /* * Create two new stream heads and attach them to the two vnodes for * the new pipe. */ if ((error = fifo_stropen(&vp1, FREAD|FWRITE, filep->f_cred, 0, 0)) != 0 || (error = fifo_stropen(&vp2, flag, filep->f_cred, 0, 0)) != 0) { #if DEBUG cmn_err(CE_NOTE, "fifo stropen failed error 0x%x", error); #endif /* * this will call fifo_close and VN_RELE on vp1 */ (void) closef(filep); VN_RELE(vp2); return (error); } /* * twist the ends of the pipe together */ strmate(vp1, vp2); /* * Set our end to busy in open * Note: Don't need lock around this because we're the only * one who knows about it */ VTOF(vp2)->fn_flag |= FIFOOPEN; mutex_enter(&fn_lock->flk_lock); fn_dest->fn_flag |= FIFOSEND; /* * check to make sure neither end of pipe has gone away */ if (!(fn_dest->fn_flag & FIFOISOPEN)) { error = ENXIO; fn_dest->fn_flag &= ~FIFOSEND; mutex_exit(&fn_lock->flk_lock); /* * this will call fifo_close and VN_RELE on vp1 */ goto out; } mutex_exit(&fn_lock->flk_lock); /* * Tag the sender's credential on the pipe descriptor. */ crhold(VTOF(vp1)->fn_pcredp = crp); VTOF(vp1)->fn_cpid = curproc->p_pid; /* * send the file descriptor to other end of pipe */ if (error = do_sendfp((*vpp)->v_stream, filep, crp)) { mutex_enter(&fn_lock->flk_lock); fn_dest->fn_flag &= ~FIFOSEND; mutex_exit(&fn_lock->flk_lock); /* * this will call fifo_close and VN_RELE on vp1 */ goto out; } mutex_enter(&fn_lock->flk_lock); /* * Wait for other end to receive file descriptor * FIFOCLOSE indicates that one or both sides of the pipe * have gone away. */ while ((fn_dest->fn_flag & (FIFOCLOSE | FIFOSEND)) == FIFOSEND) { if (!cv_wait_sig(&oldfnp->fn_wait_cv, &fn_lock->flk_lock)) { error = EINTR; fn_dest->fn_flag &= ~FIFOSEND; mutex_exit(&fn_lock->flk_lock); goto out; } } /* * If either end of pipe has gone away and the other end did not * receive pipe, reject the connld open */ if ((fn_dest->fn_flag & FIFOSEND)) { error = ENXIO; fn_dest->fn_flag &= ~FIFOSEND; mutex_exit(&fn_lock->flk_lock); goto out; } oldfnp->fn_flag &= ~FIFOOPEN; cv_broadcast(&oldfnp->fn_wait_cv); mutex_exit(&fn_lock->flk_lock); VN_RELE(*vpp); *vpp = vp2; (void) closef(filep); return (0); out: c = filep->f_cred; crhold(c); (void) closef(filep); VTOF(vp2)->fn_flag &= ~FIFOOPEN; (void) fifo_close(vp2, flag, 1, (offset_t)0, c, NULL); crfree(c); VN_RELE(vp2); return (error); }
int main(int argc, char ** argv){ unsigned int i ; long start_time, end_time ; double diff_time ; struct timespec cpu_time ; if(fifo_open(0) < 0){ printf("cannot open fifo !\n"); return -1 ; } fifo_reset(0); unsigned int size = fifo_getSize(0) ; unsigned int nb_avail = fifo_getNbAvailable(0); unsigned int nb_free = fifo_getNbFree(0); printf("fifo 0 of size %d contains %d tokens , %d free slots \n", size, nb_avail, nb_free); while(1){ fifo_reset(0); fifo_read(0, buffer, 4096); printf("done \n"); } //fifo_reset(0) ; //return 0 ; fifo_write(0, buffer, 640); sleep(3); //fifo_read(0, buffer, 1024); size = fifo_getSize(0) ; nb_avail = fifo_getNbAvailable(0); nb_free = fifo_getNbFree(0); printf("fifo 0 of size %d contains %d tokens , %d free slots \n", size, nb_avail, nb_free); return 0 ; clock_gettime(CLOCK_REALTIME, &cpu_time); start_time = cpu_time.tv_nsec ; fifo_write(0, buffer, 4096) ; clock_gettime(CLOCK_REALTIME, &cpu_time); end_time = cpu_time.tv_nsec ; diff_time = end_time - start_time ; diff_time = diff_time/1000000000.0 ; printf("transffered %d bytes in %f s : %f B/s \n", 4096, diff_time, 4096/diff_time); printf("read and write done \n"); //printf("fifo 1 is %d large and contains %d tokens \n", fifo_getSize(1), fifo_getNbAvailable(1)); /*while(1){ fifo_reset(1); fifo_read(1, buffer, 32*6); for(i = 0 ; i < 5 ; i ++){ unsigned int posx0, posy0, posx1, posy1; posy0 = buffer[i*(6)]; posy0 += (buffer[(i*(6))+1] & 0x03 << 8); posx0 = (buffer[(i*(6))+1] & 0xFC >> 2); posx0 += (buffer[(i*(6))+2] & 0x03 << 8); posy1 = (buffer[i*(6)+2] & 0xFC >> 2); posy1 += (buffer[(i*(6))+3] & 0x03 << 8); posx1 = (buffer[(i*(6))+3] & 0xFC >> 2); posx1 += (buffer[(i*(6))+4] & 0x03 << 8); printf("x[%d] = %d, y[%d] = %d \n", i, (posx0 + posx1)/2, i, (posy0 + posy1)/2); } sleep(1); }*/ //blob_tracking test ... fifo_close(0); }
/* * Stream a pipe/FIFO. * The FIFOCONNLD flag is used when CONNLD has been pushed on the stream. * If the flag is set, a new vnode is created by calling fifo_connld(). * Connld logic was moved to fifo_connld() to speed up the open * operation, simplify the connld/fifo interaction, and remove inherent * race conditions between the connld module and fifos. * This routine is single threaded for two reasons. * 1) connld requests are synchronous; that is, they must block * until the server does an I_RECVFD (oh, well). Single threading is * the simplest way to accomplish this. * 2) fifo_close() must not send M_HANGUP or M_ERROR while we are * in stropen. Stropen() has a tendency to reset things and * we would like streams to remember that a hangup occurred. */ int fifo_stropen(vnode_t **vpp, int flag, cred_t *crp, int dotwist, int lockheld) { int error = 0; vnode_t *oldvp = *vpp; fifonode_t *fnp = VTOF(*vpp); dev_t pdev = 0; int firstopen = 0; fifolock_t *fn_lock; fn_lock = fnp->fn_lock; if (!lockheld) mutex_enter(&fn_lock->flk_lock); ASSERT(MUTEX_HELD(&fnp->fn_lock->flk_lock)); /* * FIFO is in the process of opening. Wait for it * to complete before starting another open on it * This prevents races associated with connld open */ while (fnp->fn_flag & FIFOOPEN) { if (!cv_wait_sig(&fnp->fn_wait_cv, &fn_lock->flk_lock)) { fifo_cleanup(oldvp, flag); if (!lockheld) mutex_exit(&fn_lock->flk_lock); return (EINTR); } } /* * The other end of the pipe is almost closed so * reject any other open on this end of the pipe * This only happens with a pipe mounted under namefs */ if ((fnp->fn_flag & (FIFOCLOSE|ISPIPE)) == (FIFOCLOSE|ISPIPE)) { fifo_cleanup(oldvp, flag); cv_broadcast(&fnp->fn_wait_cv); if (!lockheld) mutex_exit(&fn_lock->flk_lock); return (ENXIO); } fnp->fn_flag |= FIFOOPEN; /* * can't allow close to happen while we are * in the middle of stropen(). * M_HANGUP and M_ERROR could leave the stream in a strange state */ while (fn_lock->flk_ocsync) cv_wait(&fn_lock->flk_wait_cv, &fn_lock->flk_lock); fn_lock->flk_ocsync = 1; if (fnp->fn_flag & FIFOCONNLD) { /* * This is a reopen, so we should release the fifo lock * just in case some strange module pushed on connld * has some odd side effect. * Note: this stropen is on the oldvp. It will * have no impact on the connld vp returned and * strclose() will only be called when we release * flk_ocsync */ mutex_exit(&fn_lock->flk_lock); if ((error = stropen(oldvp, &pdev, flag, crp)) != 0) { mutex_enter(&fn_lock->flk_lock); fifo_cleanup(oldvp, flag); fn_lock->flk_ocsync = 0; cv_broadcast(&fn_lock->flk_wait_cv); goto out; } /* * streams open done, allow close on other end if * required. Do this now.. it could * be a very long time before fifo_connld returns. */ mutex_enter(&fn_lock->flk_lock); /* * we need to fake an open here so that if this * end of the pipe closes, we don't loose the * stream head (kind of like single threading * open and close for this end of the pipe) * We'll need to call fifo_close() to do clean * up in case this end of the pipe was closed * down while we were in fifo_connld() */ ASSERT(fnp->fn_open > 0); fnp->fn_open++; fn_lock->flk_ocsync = 0; cv_broadcast(&fn_lock->flk_wait_cv); mutex_exit(&fn_lock->flk_lock); /* * Connld has been pushed onto the pipe * Create new pipe on behalf of connld */ if (error = fifo_connld(vpp, flag, crp)) { (void) fifo_close(oldvp, flag, 1, 0, crp, NULL); mutex_enter(&fn_lock->flk_lock); goto out; } /* * undo fake open. We need to call fifo_close * because some other thread could have done * a close and detach of the named pipe while * we were in fifo_connld(), so * we want to make sure the close completes (yuk) */ (void) fifo_close(oldvp, flag, 1, 0, crp, NULL); /* * fifo_connld has changed the vp, so we * need to re-initialize locals */ fnp = VTOF(*vpp); fn_lock = fnp->fn_lock; mutex_enter(&fn_lock->flk_lock); } else { /* * release lock in case there are modules pushed that * could have some strange side effect */ mutex_exit(&fn_lock->flk_lock); /* * If this is the first open of a fifo (dotwist * will be non-zero) we will need to twist the queues. */ if (oldvp->v_stream == NULL) firstopen = 1; /* * normal open of pipe/fifo */ if ((error = stropen(oldvp, &pdev, flag, crp)) != 0) { mutex_enter(&fn_lock->flk_lock); fifo_cleanup(oldvp, flag); ASSERT(fnp->fn_open != 0 || oldvp->v_stream == NULL); fn_lock->flk_ocsync = 0; cv_broadcast(&fn_lock->flk_wait_cv); goto out; } mutex_enter(&fn_lock->flk_lock); /* * twist the ends of the fifo together */ if (dotwist && firstopen) strmate(*vpp, *vpp); /* * Show that this open has succeeded * and allow closes or other opens to proceed */ fnp->fn_open++; fn_lock->flk_ocsync = 0; cv_broadcast(&fn_lock->flk_wait_cv); } out: fnp->fn_flag &= ~FIFOOPEN; if (error == 0) { fnp->fn_flag |= FIFOISOPEN; /* * If this is a FIFO and has the close flag set * and there are now writers, clear the close flag * Note: close flag only gets set when last writer * on a FIFO goes away. */ if (((fnp->fn_flag & (ISPIPE|FIFOCLOSE)) == FIFOCLOSE) && fnp->fn_wcnt > 0) fnp->fn_flag &= ~FIFOCLOSE; } cv_broadcast(&fnp->fn_wait_cv); if (!lockheld) mutex_exit(&fn_lock->flk_lock); return (error); }
int main(int argc, char *argv[]) { int ret; const char *url; struct sound_file_info *file; struct decode *dec; struct fifo *fifo; pthread_t tid; struct load_thread_arg arg; u8 *lrc; u8 *icon; size_t lrc_size; size_t icon_size; u8 mp3_buff[MP3_BUFF_SIZE]; u8 raw_buff[RAW_BUFF_SIZE]; int mp3_size, raw_size; struct mp3_param mp3_pm; struct audio_output *out; struct window_info *win_info; if (argc < 2) { fprintf(stderr, "Usage: %s PATH\n", argv[0]); return -EINVAL; } url = argv[1]; file = sound_file_open(url); if (NULL == file) { fprintf(stderr, "Fail to open sound file \"%s\"!\n", url); return -ENODEV; } fifo = fifo_open(); if (NULL == fifo) { goto L1; ret = -ENOMEM; } ret = parse_mp3_tag(file, &lrc, &lrc_size, &icon, &icon_size); if (ret < 0) { DPRINT("\n"); goto L2; } DPRINT("mp3_start = %lu, mp3_end = %lu, " "lrc = %p, lrc_size = %lu, icon = %p, icon_size = %lu\n", file->mp3_data_start, file->mp3_data_end, lrc, lrc_size, icon, icon_size); arg.fifo = fifo; arg.file = file; ret = pthread_create(&tid, NULL, load_mp3_data_to_fifo, &arg); if (ret < 0) { DPRINT("\n"); goto L2; } dec = decode_open(MPAUDEC); // fixme! if (NULL == dec) { ret = -ENODEV; goto L2; } while (fifo->used < fifo->size / 3) usleep(1000); mp3_size = fifo_read(fifo, mp3_buff, sizeof(mp3_buff)); get_mp3_param(dec, mp3_buff, mp3_size, &mp3_pm); win_info = window_init(); win_info->icon = icon; win_info->icon_size = icon_size; win_info->lrc = lrc; win_info->lrc_size = lrc_size; win_info->total.tv_sec = (file->mp3_data_end - file->mp3_data_start) * 8 / mp3_pm.bit_rate; win_info->total.tv_usec = (file->mp3_data_end - file->mp3_data_start) * 8 * 1000000 / mp3_pm.bit_rate % 1000000; win_info->param = &mp3_pm; DPRINT("rate = %d, channels = %d, bps = %d, bitrate = %d\n", mp3_pm.rate, mp3_pm.channels, mp3_pm.bits_per_sample, mp3_pm.bit_rate); out = open_audio(AUDIO_ALSA, &mp3_pm); if (NULL == out) { ret = -ENODEV; goto L3; } while (1) { if (file->mp3_data_end == file->offset && mp3_size == 0) break; if (mp3_size > 0) { ret = decode(dec, raw_buff, &raw_size, mp3_buff, mp3_size); mp3_size -= ret; memmove(mp3_buff, mp3_buff + ret, mp3_size); } play_frames(out, raw_buff, raw_size, &mp3_pm); ret = fifo_read(fifo, mp3_buff + mp3_size, sizeof(mp3_buff) - mp3_size); mp3_size += ret; } close_audio(out); window_destroy(); L3: decode_close(dec); L2: fifo_close(fifo); L1: sound_file_close(file); return ret; }
int main(int argc, char ** argv){ long start_time, end_time ; double diff_time ; struct timespec cpu_time ; unsigned short vsync1, vsync2 ; FILE * rgb_fd, * yuv_fd ; int i,j, res, inc = 0; unsigned int nbFrames = 1 ; unsigned int pos = 0 ; unsigned char * image_buffer, * start_buffer, * end_ptr; //yuv frame buffer unsigned char * rgb_buffer ; unsigned short fifo_state, fifo_data ; float y, u, v ; float r, g, b ; if(argc > 1){ nbFrames = atoi(argv[1]); } if(fifo_open(1) < 0 || image_buffer == 0){ printf("Error opening fifo 0 \n"); return -1 ; } image_buffer = (unsigned char *) malloc(IMAGE_WIDTH*IMAGE_HEIGHT*3); for(inc = 0 ; inc < nbFrames ; ){ sprintf(yuv_file_name, "./grabbed_frame%04d.jpg", inc); yuv_fd = fopen(yuv_file_name, "w"); if(yuv_fd == NULL){ perror("Error opening output file"); exit(EXIT_FAILURE); } //fifo_reset(1); clock_gettime(CLOCK_REALTIME, &cpu_time); start_time = cpu_time.tv_nsec ; fifo_reset(1); fifo_read(1, image_buffer, IMAGE_WIDTH*IMAGE_HEIGHT*3); clock_gettime(CLOCK_REALTIME, &cpu_time); end_time = cpu_time.tv_nsec ; diff_time = end_time - start_time ; diff_time = diff_time/1000000000 ; printf("transffered %d bytes in %f s : %f B/s \n", (IMAGE_WIDTH * IMAGE_HEIGHT*3), diff_time, (IMAGE_WIDTH * IMAGE_HEIGHT*3)/diff_time); start_buffer = image_buffer ; end_ptr = &image_buffer[IMAGE_WIDTH*IMAGE_HEIGHT*3]; vsync1 = *((unsigned short *) start_buffer) ; vsync2 = *((unsigned short *) &start_buffer[(IMAGE_WIDTH*IMAGE_HEIGHT)+2]) ; while(vsync1 != 0x55AA && vsync2 != 0x55AA && start_buffer < end_ptr){ start_buffer+=2 ; vsync1 = *((unsigned short *) start_buffer) ; vsync2 = *((unsigned short *) &start_buffer[(IMAGE_WIDTH*IMAGE_HEIGHT)+2]) ; //printf("vsync2 : %x \n", vsync2); } if(vsync1 == 0x55AA && vsync2 == 0x55AA){ inc ++ ; printf("frame found !\n"); }else{ //fclose(yuv_fd); //continue ; start_buffer = image_buffer ; inc ++ ; } start_buffer += 2 ; printf("frame captures \n"); write_jpegfile(start_buffer, IMAGE_WIDTH, IMAGE_HEIGHT, 1, yuv_fd, 100); fclose(yuv_fd); } fifo_close(1); return 0 ; }