/* Initialize global variables. */ static void init(void) { /* Default option values. */ opts.two_channel = 0; opts.multi_channel = 0; opts.output_dsf = 0; opts.output_iso = 0; opts.output_dsdiff = 0; opts.output_dsdiff_em = 0; opts.convert_dst = 0; opts.export_cue_sheet = 0; opts.print = 0; opts.input_device = "/dev/cdrom"; #ifdef _WIN32 signal(SIGINT, handle_sigint); #else struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = &handle_sigint; sigaction(SIGINT, &sa, NULL); #endif init_logging(); g_fwprintf_lock = new_lock(0); }
static int rootfs_opendir(void *_ns, void *_node, void **cookie) { nspace *ns; vnode *node; int err; dirpos *pos; ns = (nspace *) _ns; node = (vnode *) _node; if (!MY_S_ISDIR(node->mode)) { err = ENOTDIR; goto error1; } pos = (dirpos *) malloc(sizeof(dirpos)); if (!pos) { err = ENOMEM; goto error1; } if (new_lock(&pos->lock, "rootdirlock") < 0) { err = EINVAL; goto error2; } pos->pos = 0; pos->name[0] = '\0'; *cookie = pos; return 0; error2: free(pos); error1: return err; }
static PyObject *schedule_task_unblock(PyTaskletObject *prev, PyTaskletObject *next, int stackless) { PyThreadState *ts = PyThreadState_GET(); PyThreadState *nts = next->cstate->tstate; PyObject *retval; long thread_id = nts->thread_id; PyObject *unlock_lock; if (ts->st.thread.self_lock == NULL) { if (!(ts->st.thread.self_lock = new_lock())) return NULL; acquire_lock(ts->st.thread.self_lock, 1); if (!(ts->st.thread.unlock_lock = new_lock())) return NULL; if (interthread_lock == NULL) { if (!(interthread_lock = PyThread_allocate_lock())) return NULL; } } /* * make sure nobody else tries a transaction at the same time * on this tasklet's thread state, because two tasklets of the * same thread could be talking to different threads. They must * be serviced in fifo order. */ if (nts->st.thread.unlock_lock == NULL) { if (!(nts->st.thread.unlock_lock = new_lock())) return NULL; } unlock_lock = nts->st.thread.unlock_lock; Py_INCREF(unlock_lock); PyEval_SaveThread(); PR("unblocker waiting for unlocker lock"); acquire_lock(unlock_lock, 1); PR("unblocker HAS unlocker lock"); /* * also make sure that only one single interthread transaction * is performed at any time. */ PR("unblocker waiting for interthread lock"); PyThread_acquire_lock(interthread_lock, 1); PR("unblocker HAS interthread lock"); PyEval_RestoreThread(ts); /* get myself ready */ retval = slp_schedule_task(prev, prev, stackless); /* see whether the other thread still exists and is really blocked */ if (is_thread_alive(thread_id) && nts->st.thread.is_locked) { /* tell the blocker what comes next */ temp.unlock_target = next; temp.other_lock = ts->st.thread.self_lock; /* give it an extra ref, in case I would die early */ Py_INCREF(temp.other_lock); /* unblock it */ release_lock(nts->st.thread.self_lock); /* wait for the transaction to finish */ PyEval_SaveThread(); PR("unblocker waiting for own lock"); acquire_lock(ts->st.thread.self_lock, 1); PR("unblocker HAS own lock"); PyEval_RestoreThread(ts); } else { PR("unlocker: other is NOT LOCKED or dead"); if (next->flags.blocked) { /* unblock from channel */ slp_channel_remove_slow(next); slp_current_insert(next); } else if (next->next == NULL) { /* reactivate floating task */ Py_INCREF(next); slp_current_insert(next); } } PR("unblocker releasing interthread lock"); PyThread_release_lock(interthread_lock); PR("unblocker RELEASED interthread lock"); PR("unblocker releasing unlocker lock"); release_lock(unlock_lock); Py_DECREF(unlock_lock); PR("unblocker RELEASED unlocker lock"); return retval; }
static PyObject * schedule_task_block(PyTaskletObject *prev, int stackless) { PyThreadState *ts = PyThreadState_GET(); PyObject *retval; PyTaskletObject *next = NULL; PyObject *unlocker_lock; if (check_for_deadlock()) { /* revive real main if floating */ if (ts == slp_initial_tstate && ts->st.main->next == NULL) { /* emulate old revive_main behavior: * passing a value only if it is an exception */ if (PyBomb_Check(prev->tempval)) TASKLET_SETVAL(ts->st.main, prev->tempval); return slp_schedule_task(prev, ts->st.main, stackless); } if (!(retval = make_deadlock_bomb())) return NULL; TASKLET_SETVAL_OWN(prev, retval); return slp_schedule_task(prev, prev, stackless); } #ifdef WITH_THREAD if (ts->st.thread.self_lock == NULL) { if (!(ts->st.thread.self_lock = new_lock())) return NULL; acquire_lock(ts->st.thread.self_lock, 1); if (!(ts->st.thread.unlock_lock = new_lock())) return NULL; } /* let somebody reactivate us */ ts->st.thread.is_locked = 1; /* flag as blocked and wait */ PyEval_SaveThread(); PR("locker waiting for my lock"); acquire_lock(ts->st.thread.self_lock, 1); PR("HAVE my lock"); PyEval_RestoreThread(ts); if (temp.unlock_target != NULL) { next = temp.unlock_target; temp.unlock_target = NULL; } else next = prev; /* * get in shape. can't do this with schedule here because * hard switching might not get us back, soon enough. */ if (next->flags.blocked) { /* unblock from channel */ slp_channel_remove_slow(next); slp_current_insert(next); } else if (next->next == NULL) { /* reactivate floating task */ Py_INCREF(next); slp_current_insert(next); } if (temp.other_lock != NULL) { PR("releasing unlocker"); unlocker_lock = temp.other_lock; temp.other_lock = NULL; release_lock(unlocker_lock); Py_DECREF(unlocker_lock); } ts->st.thread.is_locked = 0; #else (void)unlocker_lock; next = prev; #endif /* this must be after releasing the locks because of hard switching */ retval = slp_schedule_task(prev, next, stackless); PR("schedule() is done"); return retval; }
static int rootfs_mount(nspace_id nsid, const char *device, ulong flags, void *parms, size_t len, void **data, vnode_id *vnid) { int err; nspace *ns; vnode *root; vnode_id rvnid; if (device || parms || (len != 0)) { err = EINVAL; goto error1; } ns = (nspace *) malloc(sizeof(nspace)); if (!ns) { err = ENOMEM; goto error1; } root = (vnode *) malloc(sizeof(vnode)); if (!root) { err = ENOMEM; goto error2; } rvnid = 1; ns->nsid = nsid; ns->vnnum = 0; ns->nxvnid = rvnid; ns->root = root; if (new_lock(&ns->lock, "rootfs") < 0) { err = -1; goto error3; } ns->skiplist = NewSL(&compare_vnode, NULL, NO_DUPLICATES); if (!ns->skiplist) { err = -1; goto error4; } root->vnid = rvnid; root->parent = root; root->ns = ns; root->removed = FALSE; root->name = NULL; root->next = root->prev = NULL; root->head = NULL; root->symlink = NULL; /* ### do it for real */ root->uid = 0; root->gid = 0; root->mode = MY_S_IFDIR | 0777; root->mtime = time(NULL); err = new_vnode(nsid, rvnid, root); if (err) goto error5; *data = ns; *vnid = rvnid; return 0; error5: FreeSL(ns->skiplist); error4: free_lock(&ns->lock); error3: free(root); error2: free(ns); error1: return err; }