int main(int argc, char *argv[]) { int fd; int ret; struct flock lock; char read_buf[32]; // 打开或创建文件 if ((fd = open("example_fc_lock", O_CREAT | O_TRUNC | O_RDWR, S_IRWXU)) == -1) { my_err("open", __LINE__); } if (write(fd, "test lock", 10) != 10) { my_err("write", __LINE__); } // 初始化lock结构 锁整个文件 memset(&lock, 0, sizeof(struct flock)); lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; // 设置读锁 lock.l_type = F_RDLCK; if (lock_test(fd, &lock) == 0) { // 测试可以设置锁 lock.l_type = F_RDLCK; lock_set(fd, &lock); } // 读数据 lseek(fd, 0, SEEK_SET); if ((ret = read(fd, read_buf, 10)) < 0) { my_err("read", __LINE__); } read_buf[ret] = '\0'; printf("%s\n", read_buf); // 按任意键 getchar(); // 设置写锁 lock.l_type = F_WRLCK; if (lock_test(fd, &lock) == 0) { lock.l_type = F_WRLCK; lock_set(fd, &lock); } // 释放锁 lock.l_type = F_UNLCK; lock_set(fd, &lock); close(fd); return 0; }
int main(int argc, char *argv[]) { if(argc < 3) { printf("usage: ./main filename locktype\n"); return -1; } int fd = open(argv[1], O_RDWR); if(fd < 0) { perror("file open fail"); return -1; } int type = atoi(argv[2]); short locktype; if(type == 0) { locktype = F_RDLCK; //should not set F_UNLCK first, it is always success, but a new process can not unlock another proceess's lock } //A rd or wr lock only can be unlock by the same process's unlock else { locktype = F_WRLCK; } int ret = lock_set(locktype, fd); if(ret < 0) { perror("lock file fail"); return -1; } else printf("lockType %d success on file %s\n", atoi(argv[2]), argv[1]); sleep(10); ret = lock_set(F_UNLCK, fd); if(ret < 0) { perror("lock file fail"); return -1; } else printf("lockType %d success on file %s\n", atoi(argv[2]), argv[1]); while(1); }
int main(void){ int fd; int ret; struct flock lock; char read_buf[32]; if((fd = open("example_65", O_CREAT|O_TRUNC|O_RDWR, S_IRWXU)) == -1){ my_err("open", __LINE__); } if(write(fd, "test lock", 10) != 10){ my_err("write", __LINE__); } memset(&lock, 0, sizeof(struct flock)); lock.l_start = SEEK_SET; lock.l_whence = 0; lock.l_len = 0; lock.l_type = F_RDLCK; if(lock_test(fd, &lock) == 0){ lock.l_type = F_RDLCK; lock_set(fd, &lock); } lseek(fd, 0, SEEK_SET); bzero(read_buf, 10); if((ret = read(fd, read_buf, 10)) < 0){ printf("%d\n", errno); my_err("read", __LINE__); } read_buf[ret] = '\0'; printf("%s\n", read_buf); getchar(); lock.l_type = F_WRLCK; if(lock_test(fd, &lock) == 0){ lock.l_type = F_WRLCK; lock_set(fd, &lock); } lock.l_type = F_UNLCK; lock_set(fd, &lock); close(fd); return 0; }
int main(void) { int fd; fd = open("hello",O_RDWR | O_CREAT, 0666); if (fd < 0) { perror("open"); exit(1); } lock_set(fd, F_WRLCK); getchar(); lock_set(fd, F_UNLCK); getchar(); close(fd); exit(0); }
/* * When we apply priority inheritance, we must grab the owner's thread lock * while already holding the waiter's thread lock. If both thread locks are * turnstile locks, this can lead to deadlock: while we hold L1 and try to * grab L2, some unrelated thread may be applying priority inheritance to * some other blocking chain, holding L2 and trying to grab L1. The most * obvious solution -- do a lock_try() for the owner lock -- isn't quite * sufficient because it can cause livelock: each thread may hold one lock, * try to grab the other, fail, bail out, and try again, looping forever. * To prevent livelock we must define a winner, i.e. define an arbitrary * lock ordering on the turnstile locks. For simplicity we declare that * virtual address order defines lock order, i.e. if L1 < L2, then the * correct lock ordering is L1, L2. Thus the thread that holds L1 and * wants L2 should spin until L2 is available, but the thread that holds * L2 and can't get L1 on the first try must drop L2 and return failure. * Moreover, the losing thread must not reacquire L2 until the winning * thread has had a chance to grab it; to ensure this, the losing thread * must grab L1 after dropping L2, thus spinning until the winner is done. * Complicating matters further, note that the owner's thread lock pointer * can change (i.e. be pointed at a different lock) while we're trying to * grab it. If that happens, we must unwind our state and try again. * * On success, returns 1 with both locks held. * On failure, returns 0 with neither lock held. */ static int turnstile_interlock(lock_t *wlp, lock_t *volatile *olpp) { ASSERT(LOCK_HELD(wlp)); for (;;) { volatile lock_t *olp = *olpp; /* * If the locks are identical, there's nothing to do. */ if (olp == wlp) return (1); if (lock_try((lock_t *)olp)) { /* * If 'olp' is still the right lock, return success. * Otherwise, drop 'olp' and try the dance again. */ if (olp == *olpp) return (1); lock_clear((lock_t *)olp); } else { hrtime_t spin_time = 0; /* * If we're grabbing the locks out of order, we lose. * Drop the waiter's lock, and then grab and release * the owner's lock to ensure that we won't retry * until the winner is done (as described above). */ if (olp >= (lock_t *)turnstile_table && olp < wlp) { lock_clear(wlp); lock_set((lock_t *)olp); lock_clear((lock_t *)olp); return (0); } /* * We're grabbing the locks in the right order, * so spin until the owner's lock either becomes * available or spontaneously changes. */ spin_time = LOCKSTAT_START_TIME(LS_TURNSTILE_INTERLOCK_SPIN); while (olp == *olpp && LOCK_HELD(olp)) { if (panicstr) return (1); SMT_PAUSE(); } LOCKSTAT_RECORD_TIME(LS_TURNSTILE_INTERLOCK_SPIN, olp, spin_time); } } }
int zrip_unlock_cdrom( int fd ) { ZInfo4(DBG_MISC, "Try to unlock the cdrom\n"); if(!fd) return -1; lock_set( fd, F_UNLCK ); if ( close(fd) < 0 ){ return -1; } ZInfo4(DBG_MISC, "cdrom unlocked\n"); return 0; }
int zrip_lock_cdrom( char *fileName ) { int fd = 0; ZInfo4(DBG_MISC, "Try to lock the cdrom\n"); if( ( fd = open( fileName, O_CREAT | O_TRUNC | O_RDWR, 0666 ) ) < 0 ){ ZInfo4(DBG_MISC, "open lock file failed!\n"); return 0; } lock_set( fd, F_WRLCK ); ZInfo4(DBG_MISC, "cdrom locked\n"); return fd; }
void sys_log(char * string) { int fd; char str[SIZE]; time_t timep; struct tm *timenow; char log[SIZE]; struct flock lock; memset(&lock, 0, sizeof(struct flock)); lock.l_start = SEEK_SET; lock.l_whence = 0; lock.l_len = 0; lock.l_type = F_WRLCK; if (lock_test(fd, &lock) == 0) { lock.l_type = F_WRLCK; lock_set(fd, &lock); } strcpy(log, string); time (&timep); timenow = localtime(&timep); strcpy(str, asctime(timenow)); fd = open("/home/qiong/shujia/Net/sys_log.txt", O_WRONLY | O_CREAT | O_APPEND, 0600); write(fd, "\n\n时间:", strlen("\n\n时间:")); write(fd, str, strlen(str)-1); write(fd, "\nip:", strlen("\nip:")); write(fd, ip_name, strlen(ip_name)); write(fd, "\n操作:", strlen("\n操作:")); write(fd, log, strlen(log)); lock.l_type = F_UNLCK; lock_set(fd, &lock); close(fd); }
int product(void) { int fd; unsigned int sign_type,sign_start,sign_count,size; static unsigned int counter = 0; if((fd = open(fifo_file, O_CREAT|O_RDWR|O_APPEND, 0644)) < 0){ printf("Open fifo file error\n"); exit(1); } sign_type = SIGN_TYPE; switch(sign_type) { case ALPHABET: sign_start = ALPHABET_START; sign_count = COUNT_OF_ALPHABET; break; case DIGIT: sign_start = DIGIT_START; sign_count = COUNT_OF_DIGIT; break; default: return -1; } sprintf(buff, "%c", (sign_start + counter)); counter = (counter + 1) % sign_count; lock_set(fd,F_WRLCK); if((size = write(fd,buff,strlen(buff))) < 0) { printf("Producter:write error\n"); return -1; } lock_set(fd,F_UNLCK); close(fd); return 0; }
int main(int ac, char **av) { (void)(ac); lock_path = strdup(av[1]); if (action_is("lock_exists")) { printf("%d\n", lock_exists()); } else if (action_is("lock_set")) { lock_set(); } else if (action_is("lock_unset")) { lock_unset(); } return EXIT_SUCCESS; }
void transfer_rename(const char *to) { size_t to_len; pthread_mutex_lock(&m_transfer); if (!t_state.active) { pthread_mutex_unlock(&m_transfer); return; } DEBUG("transfer_rename to %s", to); to_len = strlen(to); worker_block(); lock_remove(t_state.job->path, LOCK_TRANSFER); free(t_state.job->path); t_state.job->path = strdup(to); lock_set(t_state.job->path, LOCK_TRANSFER); free(t_state.read_path); free(t_state.write_path); if (t_state.job->op == JOB_PUSH) { t_state.read_path = cache_path2(to, to_len); t_state.write_path = remote_path2(to, to_len); } else { t_state.read_path = remote_path2(to, to_len); t_state.write_path = cache_path2(to, to_len); } pthread_mutex_unlock(&m_transfer); worker_unblock(); }
CosConcurrencyControl::LockSet_ptr CC_Test::create_lock_set (void) { // Create the lock set and return an obj ref corresponding to the // key. CosConcurrencyControl::LockSet_ptr lock_set(0); try { lock_set = this->naming_service_->get_lock_set_factory ()->create (); if (CORBA::is_nil (lock_set)) ACE_ERROR_RETURN ((LM_ERROR, "null lock set objref returned by factory\n"), 0); } catch (const CORBA::Exception& ex) { ex._tao_print_exception ("CC_Client::create_lock_set"); return 0; } return lock_set; }
int main(int ac, char **av) { char *t; int opt, mode = MODE_PAGER; extern int optind; extern char *optarg; if (ac < 2) usage(); setlocale(LC_ALL, ""); /* Populate $HOME */ t = getenv("HOME"); if (t == NULL || *t == '\0') errx(0, "Unknown variable '$HOME'."); mbstowcs(home, t, MAXPATHLEN); /* Populate $EDITOR */ t = getenv("EDITOR"); if (t != NULL) mbstowcs(editor, t, MAXPATHLEN); while ((opt = getopt(ac, av, "hVdeg:qrc:")) != -1) { switch (opt) { case 'd': cfg_debug = 1; break; case 'V': mode = MODE_VERSION; break; case 'q': mode = MODE_QUERY; break; case 'e': mode = MODE_EDIT; break; case 'g': mode = MODE_GENERATE; password_length = strtoumax(optarg, NULL, 10); break; case 'r': mode = MODE_RAW; break; case 'c': swprintf(cfg_config_path, MAXPATHLEN, L"%s", optarg); break; default: usage(); } } debug("read config"); config_set_defaults(); config_check_paths(); config_read(); ac -= optind; av += optind; keywords_load_from_argv(av); /* Decide if we use the internal pager or just dump to screen. */ switch (mode) { case MODE_VERSION: printf("mdp-%s\n", MDP_VERSION); break; case MODE_RAW: debug("mode: MODE_RAW"); if (ac == 0) usage(); gpg_check(); load_results(); filter_results(); print_results(); break; case MODE_PAGER: debug("mode: MODE_PAGER"); if (ac == 0) usage(); gpg_check(); load_results(); filter_results(); pager(START_WITHOUT_PROMPT); break; case MODE_QUERY: debug("mode: MODE_QUERY"); gpg_check(); load_results(); pager(START_WITH_PROMPT); break; case MODE_EDIT: debug("mode: MODE_EDIT"); if (ac != 0) usage(); gpg_check(); lock_set(); load_results(); edit_results(); break; case MODE_GENERATE: debug("mode: MODE_GENERATE"); if (ac != 0) usage(); print_passwords(password_length, cfg_password_count); break; default: errx(1, "unknown mode"); break; } debug("normal shutdown"); return 0; }
int turnstile_block(turnstile_t *ts, int qnum, void *sobj, sobj_ops_t *sobj_ops, kmutex_t *mp, lwp_timer_t *lwptp) { kthread_t *owner; kthread_t *t = curthread; proc_t *p = ttoproc(t); klwp_t *lwp = ttolwp(t); turnstile_chain_t *tc = &TURNSTILE_CHAIN(sobj); int error = 0; int loser = 0; ASSERT(DISP_LOCK_HELD(&tc->tc_lock)); ASSERT(mp == NULL || IS_UPI(mp)); ASSERT((SOBJ_TYPE(sobj_ops) == SOBJ_USER_PI) ^ (mp == NULL)); thread_lock_high(t); if (ts == NULL) { /* * This is the first thread to block on this sobj. * Take its attached turnstile and add it to the hash chain. */ ts = t->t_ts; ts->ts_sobj = sobj; ts->ts_next = tc->tc_first; tc->tc_first = ts; ASSERT(ts->ts_waiters == 0); } else { /* * Another thread has already donated its turnstile * to block on this sobj, so ours isn't needed. * Stash it on the active turnstile's freelist. */ turnstile_t *myts = t->t_ts; myts->ts_free = ts->ts_free; ts->ts_free = myts; t->t_ts = ts; ASSERT(ts->ts_sobj == sobj); ASSERT(ts->ts_waiters > 0); } /* * Put the thread to sleep. */ ASSERT(t != CPU->cpu_idle_thread); ASSERT(CPU_ON_INTR(CPU) == 0); ASSERT(t->t_wchan0 == NULL && t->t_wchan == NULL); ASSERT(t->t_state == TS_ONPROC); if (SOBJ_TYPE(sobj_ops) == SOBJ_USER_PI) { curthread->t_flag |= T_WAKEABLE; } CL_SLEEP(t); /* assign kernel priority */ THREAD_SLEEP(t, &tc->tc_lock); t->t_wchan = sobj; t->t_sobj_ops = sobj_ops; DTRACE_SCHED(sleep); if (lwp != NULL) { lwp->lwp_ru.nvcsw++; (void) new_mstate(t, LMS_SLEEP); if (SOBJ_TYPE(sobj_ops) == SOBJ_USER_PI) { lwp->lwp_asleep = 1; lwp->lwp_sysabort = 0; /* * make wchan0 non-zero to conform to the rule that * threads blocking for user-level objects have a * non-zero wchan0: this prevents spurious wake-ups * by, for example, /proc. */ t->t_wchan0 = (caddr_t)1; } } ts->ts_waiters++; sleepq_insert(&ts->ts_sleepq[qnum], t); if (SOBJ_TYPE(sobj_ops) == SOBJ_MUTEX && SOBJ_OWNER(sobj_ops, sobj) == NULL) panic("turnstile_block(%p): unowned mutex", (void *)ts); /* * Follow the blocking chain to its end, willing our priority to * everyone who's in our way. */ while (t->t_sobj_ops != NULL && (owner = SOBJ_OWNER(t->t_sobj_ops, t->t_wchan)) != NULL) { if (owner == curthread) { if (SOBJ_TYPE(sobj_ops) != SOBJ_USER_PI) { panic("Deadlock: cycle in blocking chain"); } /* * If the cycle we've encountered ends in mp, * then we know it isn't a 'real' cycle because * we're going to drop mp before we go to sleep. * Moreover, since we've come full circle we know * that we must have willed priority to everyone * in our way. Therefore, we can break out now. */ if (t->t_wchan == (void *)mp) break; if (loser) lock_clear(&turnstile_loser_lock); /* * For SOBJ_USER_PI, a cycle is an application * deadlock which needs to be communicated * back to the application. */ thread_unlock_nopreempt(t); mutex_exit(mp); setrun(curthread); swtch(); /* necessary to transition state */ curthread->t_flag &= ~T_WAKEABLE; if (lwptp->lwpt_id != 0) (void) lwp_timer_dequeue(lwptp); setallwatch(); lwp->lwp_asleep = 0; lwp->lwp_sysabort = 0; return (EDEADLK); } if (!turnstile_interlock(t->t_lockp, &owner->t_lockp)) { /* * If we failed to grab the owner's thread lock, * turnstile_interlock() will have dropped t's * thread lock, so at this point we don't even know * that 't' exists anymore. The simplest solution * is to restart the entire priority inheritance dance * from the beginning of the blocking chain, since * we *do* know that 'curthread' still exists. * Application of priority inheritance is idempotent, * so it's OK that we're doing it more than once. * Note also that since we've dropped our thread lock, * we may already have been woken up; if so, our * t_sobj_ops will be NULL, the loop will terminate, * and the call to swtch() will be a no-op. Phew. * * There is one further complication: if two (or more) * threads keep trying to grab the turnstile locks out * of order and keep losing the race to another thread, * these "dueling losers" can livelock the system. * Therefore, once we get into this rare situation, * we serialize all the losers. */ if (loser == 0) { loser = 1; lock_set(&turnstile_loser_lock); } t = curthread; thread_lock_high(t); continue; } /* * We now have the owner's thread lock. If we are traversing * from non-SOBJ_USER_PI ops to SOBJ_USER_PI ops, then we know * that we have caught the thread while in the TS_SLEEP state, * but holding mp. We know that this situation is transient * (mp will be dropped before the holder actually sleeps on * the SOBJ_USER_PI sobj), so we will spin waiting for mp to * be dropped. Then, as in the turnstile_interlock() failure * case, we will restart the priority inheritance dance. */ if (SOBJ_TYPE(t->t_sobj_ops) != SOBJ_USER_PI && owner->t_sobj_ops != NULL && SOBJ_TYPE(owner->t_sobj_ops) == SOBJ_USER_PI) { kmutex_t *upi_lock = (kmutex_t *)t->t_wchan; ASSERT(IS_UPI(upi_lock)); ASSERT(SOBJ_TYPE(t->t_sobj_ops) == SOBJ_MUTEX); if (t->t_lockp != owner->t_lockp) thread_unlock_high(owner); thread_unlock_high(t); if (loser) lock_clear(&turnstile_loser_lock); while (mutex_owner(upi_lock) == owner) { SMT_PAUSE(); continue; } if (loser) lock_set(&turnstile_loser_lock); t = curthread; thread_lock_high(t); continue; } turnstile_pi_inherit(t->t_ts, owner, DISP_PRIO(t)); if (t->t_lockp != owner->t_lockp) thread_unlock_high(t); t = owner; } if (loser) lock_clear(&turnstile_loser_lock); /* * Note: 't' and 'curthread' were synonymous before the loop above, * but now they may be different. ('t' is now the last thread in * the blocking chain.) */ if (SOBJ_TYPE(sobj_ops) == SOBJ_USER_PI) { ushort_t s = curthread->t_oldspl; int timedwait = 0; uint_t imm_timeout = 0; clock_t tim = -1; thread_unlock_high(t); if (lwptp->lwpt_id != 0) { /* * We enqueued a timeout. If it has already fired, * lwptp->lwpt_imm_timeout has been set with cas, * so fetch it with cas. */ timedwait = 1; imm_timeout = atomic_cas_uint(&lwptp->lwpt_imm_timeout, 0, 0); } mutex_exit(mp); splx(s); if (ISSIG(curthread, JUSTLOOKING) || MUSTRETURN(p, curthread) || imm_timeout) setrun(curthread); swtch(); curthread->t_flag &= ~T_WAKEABLE; if (timedwait) tim = lwp_timer_dequeue(lwptp); setallwatch(); if (ISSIG(curthread, FORREAL) || lwp->lwp_sysabort || MUSTRETURN(p, curthread)) error = EINTR; else if (imm_timeout || (timedwait && tim == -1)) error = ETIME; lwp->lwp_sysabort = 0; lwp->lwp_asleep = 0; } else { thread_unlock_nopreempt(t); swtch(); } return (error); }
int transfer(const char *from, const char *to) { #define CLOSE(fd) { if (close(fd)) PERROR("error closing fd"); } int fdread, fdwrite; ssize_t readbytes; char buf[TRANSFER_SIZE]; int w_flags; pthread_mutex_lock(&m_transfer); if (from && to) { lock_set(t_state.job->path, LOCK_TRANSFER); VERBOSE("beginning transfer: '%s' -> '%s'", from, to); t_state.read_path = strdup(from); t_state.write_path = strdup(to); w_flags = O_WRONLY | O_CREAT | O_TRUNC; } else if (!t_state.active) { pthread_mutex_unlock(&m_transfer); return TRANSFER_FINISH; } else { VERBOSE("resuming transfer: '%s' -> '%s' at %ld", t_state.read_path, t_state.write_path, t_state.offset); w_flags = O_WRONLY | O_APPEND; } if (!t_state.read_path || !t_state.write_path) { ERROR("t_state.read_path or t_state.write_path is NULL"); lock_remove(t_state.job->path, LOCK_TRANSFER); goto failure; } /* open files */ if ((fdread = open(t_state.read_path, O_RDONLY)) == -1 || lseek(fdread, t_state.offset, SEEK_SET) == -1) { PERROR(t_state.read_path); goto failure; } if ((fdwrite = open(t_state.write_path, w_flags, 0666)) == -1 || lseek(fdwrite, t_state.offset, SEEK_SET) == -1) { PERROR(t_state.write_path); goto failure; } while (ONLINE && !worker_blocked()) { readbytes = read(fdread, buf, sizeof buf); if (readbytes && (readbytes < 0 || write(fdwrite, buf, readbytes) < readbytes || fsync(fdwrite))) { if (readbytes < 0) ERROR("failed to read from file"); else ERROR("failed or incomplete write"); goto failure; } /* copy completed, set mode and ownership */ if (readbytes < sizeof buf) { CLOSE(fdread); CLOSE(fdwrite); copy_attrs(t_state.read_path, t_state.write_path); VERBOSE("transfer finished: '%s' -> '%s'", t_state.read_path, t_state.write_path); lock_remove(t_state.job->path, LOCK_TRANSFER); pthread_mutex_unlock(&m_transfer); transfer_reset_state(); return TRANSFER_FINISH; } } t_state.offset = lseek(fdread, 0, SEEK_CUR); CLOSE(fdread); CLOSE(fdwrite); pthread_mutex_unlock(&m_transfer); return TRANSFER_OK; failure: pthread_mutex_unlock(&m_transfer); transfer_abort(); return TRANSFER_FAIL; #undef CLOSE }