void tls_prng_exch_update(TLS_PRNG_SRC *eh) { const char *myname = "tls_prng_exch_update"; unsigned char buffer[TLS_PRNG_EXCH_SIZE]; ssize_t count; /* * Update the PRNG exchange file. Since other processes may have added * entropy, we use a read-stir-write cycle. */ if (acl_myflock(eh->fd.file, ACL_INTERNAL_LOCK, ACL_MYFLOCK_OP_EXCLUSIVE) != 0) acl_msg_fatal("%s: cannot lock PRNG exchange file %s: %s", myname, eh->name, acl_last_serror()); if (acl_lseek(eh->fd.file, 0, SEEK_SET) < 0) acl_msg_fatal("%s: cannot seek PRNG exchange file %s: %s", myname, eh->name, acl_last_serror()); if ((count = acl_file_read(eh->fd.file, buffer, sizeof(buffer), 0, NULL)) < 0) acl_msg_fatal("%s: cannot read PRNG exchange file %s: %s", myname, eh->name, acl_last_serror()); if (count > 0) RAND_seed(buffer, count); RAND_bytes(buffer, sizeof(buffer)); if (acl_lseek(eh->fd.file, 0, SEEK_SET) < 0) acl_msg_fatal("%s: cannot seek PRNG exchange file %s: %s", myname, eh->name, acl_last_serror()); if (acl_file_write(eh->fd.file, buffer, sizeof(buffer), 0, NULL) != sizeof(buffer)) acl_msg_fatal("%s: cannot write PRNG exchange file %s: %s", myname, eh->name, acl_last_serror()); if (acl_myflock(eh->fd.file, ACL_INTERNAL_LOCK, ACL_MYFLOCK_OP_NONE) != 0) acl_msg_fatal("%s: cannot unlock PRNG exchange file %s: %s", myname, eh->name, acl_last_serror()); }
TLS_SCACHE *tls_scache_open(const char *dbname, const char *cache_label, int verbose, int timeout) { const char *myname = "tls_scache_open"; TLS_SCACHE *cp; DICT *dict; /* * Logging. */ if (verbose) acl_msg_info("open %s TLS cache %s", cache_label, dbname); /* * Open the dictionary with O_TRUNC, so that we never have to worry about * opening a damaged file after some process terminated abnormally. */ #ifdef SINGLE_UPDATER #define DICT_FLAGS (DICT_FLAG_DUP_REPLACE) #elif defined(ACL_UNIX) #define DICT_FLAGS \ (DICT_FLAG_DUP_REPLACE | DICT_FLAG_LOCK | DICT_FLAG_SYNC_UPDATE) #elif defined(WIN32) #define DICT_FLAGS \ (DICT_FLAG_DUP_REPLACE | DICT_FLAG_SYNC_UPDATE) #endif dict = dict_open(dbname, O_RDWR | O_CREAT | O_TRUNC, DICT_FLAGS); /* * Sanity checks. */ if (dict->lock_fd < 0) acl_msg_fatal("%s: dictionary %s is not a regular file", myname, dbname); #ifdef SINGLE_UPDATER if (acl_myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE | MYFLOCK_OP_NOWAIT) < 0) acl_msg_fatal("%s: cannot lock dictionary %s for exclusive use: %s", myname, dbname, acl_last_serror()); #endif if (dict->update == 0) acl_msg_fatal("%s: dictionary %s does not support update operations", myname, dbname); if (dict->delete_it == 0) acl_msg_fatal("%s: dictionary %s does not support delete operations", myname, dbname); if (dict->sequence == 0) acl_msg_fatal("%s: dictionary %s does not support sequence operations", myname, dbname); /* * Create the TLS_SCACHE object. */ cp = (TLS_SCACHE *) acl_mymalloc(sizeof(*cp)); cp->flags = 0; cp->db = dict; cp->cache_label = acl_mystrdup(cache_label); cp->verbose = verbose; cp->timeout = timeout; cp->saved_cursor = 0; return (cp); }
bool locker::lock() { #ifdef ACL_HAS_SPINLOCK if (spinlock_) { if (pthread_spin_lock(spinlock_) != 0) return false; } else #endif if (mutex_) { if (acl_pthread_mutex_lock(mutex_) != 0) return false; } if (fHandle_ == ACL_FILE_INVALID) return true; int operation = ACL_FLOCK_OP_EXCLUSIVE; if (acl_myflock(fHandle_, ACL_FLOCK_STYLE_FCNTL, operation) == 0) return true; if (mutex_) acl_assert(acl_pthread_mutex_unlock(mutex_) == 0); return false; }
bool locker::unlock() { bool ret; #ifdef ACL_HAS_SPINLOCK if (spinlock_) { if (pthread_spin_unlock(spinlock_) == 0) ret = true; else ret = false; } else #endif if (mutex_) { if (acl_pthread_mutex_unlock(mutex_) == 0) ret = true; else ret = false; } else ret = true; if (fHandle_ == ACL_FILE_INVALID) return ret; int operation = ACL_FLOCK_STYLE_FCNTL; if (acl_myflock(fHandle_, operation, ACL_FLOCK_OP_NONE) == -1) return false; return ret; }
ACL_VSTREAM *local_listen() { const char *myname = "local_listen"; char lock_file[MAX_PATH], ebuf[256]; ACL_VSTREAM *sstream, *fp; ACL_FILE_HANDLE handle; get_lock_file(lock_file, sizeof(lock_file)); fp = acl_vstream_fopen(lock_file, O_RDWR | O_CREAT, 0600, 1024); if (fp == NULL) acl_msg_fatal("%s(%d): open file(%s) error(%s)", myname, __LINE__, lock_file, acl_last_strerror(ebuf, sizeof(ebuf))); handle = ACL_VSTREAM_FILE(fp); if (acl_myflock(handle, 0, ACL_MYFLOCK_OP_EXCLUSIVE | ACL_MYFLOCK_OP_NOWAIT) == -1) { acl_msg_error("%s(%d): lock file(%s) error(%s)", myname, __LINE__, lock_file, acl_last_strerror(ebuf, sizeof(ebuf))); return (NULL); } sstream = acl_vstream_listen_ex("127.0.0.1:0", 128, ACL_BLOCKING, 1024, 0); if (sstream == NULL) acl_msg_fatal("%s(%d): listen error(%s)", myname, __LINE__, acl_last_strerror(ebuf, sizeof(ebuf))); if (acl_file_ftruncate(fp, 0) < 0) acl_msg_fatal("%s(%d): truncate file(%s) error(%s)", myname, __LINE__, lock_file, acl_last_strerror(ebuf, sizeof(ebuf))); if (acl_vstream_fseek(fp, 0, SEEK_SET) < 0) acl_msg_fatal("%s(%d): fseek file(%s) error(%s)", myname, __LINE__, lock_file, acl_last_strerror(ebuf, sizeof(ebuf))); if (acl_vstream_fprintf(fp, "%s\r\n", sstream->local_addr) == ACL_VSTREAM_EOF) acl_msg_fatal("%s(%d): fprintf to file(%s) error(%s)", myname, __LINE__, lock_file, acl_last_strerror(ebuf, sizeof(ebuf))); /* XXX: 只能采用先解排它锁,再加共享锁,微软比较弱!!! */ if (acl_myflock(handle, 0, ACL_MYFLOCK_OP_NONE) == -1) acl_msg_fatal("%s(%d): unlock file(%s) error(%s)", myname, __LINE__, lock_file, acl_last_strerror(ebuf, sizeof(ebuf))); if (acl_myflock(handle, 0, ACL_MYFLOCK_OP_SHARED | ACL_MYFLOCK_OP_NOWAIT) == -1) acl_msg_fatal("%s(%d): lock file(%s) error(%s)", myname, __LINE__, lock_file, acl_last_strerror(ebuf, sizeof(ebuf))); return (sstream); }
static int __mylock_op(ACL_FILE_HANDLE fd, int op, char *errbuf, int size) { int lock_style = ACL_FLOCK_STYLE_FCNTL; int ret; ret = acl_myflock(fd, lock_style, op); if (ret < 0) { if (errbuf && size > 0) snprintf(errbuf, size, "flock error(%s)", strerror(errno)); return (-1); } return (0); }