void operator()(const char *filepath, const char *filename) { std::string pid_str; //If the lock file is not our own lock file, then try to do the cleanup if(!intermodule_singleton_helpers::check_if_filename_complies_with_pid (filename, robust_lock_prefix(), get_current_process_id(), pid_str)){ remove_if_can_lock_file(filepath); } }
void print_B(){ int i = 0; print_B_process = get_current_process_id(); for(;;){ kprint("B"); for(i=0; i < 10000000; i++){ } resume_process(print_A_process); } }
void print_A(){ int i = 0; print_A_process = get_current_process_id(); for(;;){ kprint("A"); for(i=0; i < 10000000; i++){ } suspend_current_process(); } }
inline void robust_spin_mutex<Mutex>::consistent() { //This function supposes the previous state was "fixing" //and the current process holds the mutex if(atomic_read32(&this->state) != fixing_state && atomic_read32(&this->owner) != (boost::uint32_t)get_current_process_id()){ throw interprocess_exception(lock_error, "Broken id"); } //If that's the case, just update mutex state atomic_write32(&this->state, correct_state); }
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved) { (void) hModule; (void) lpReserved; if(dwReason == DLL_PROCESS_ATTACH && is_ignored_process() == 0) { monitor_init(hModule); monitor_hook(NULL); pipe("LOADED:%d,%d", get_current_process_id(), g_monitor_track); } return TRUE; }
robust_mutex_lock_file() { permissions p; p.set_unrestricted(); //Remove old lock files of other processes remove_old_robust_lock_files(); //Create path and obtain lock file path for this process create_and_get_robust_lock_file_path(fname, get_current_process_id()); //Now try to open or create the lock file fd = create_or_open_file(fname.c_str(), read_write, p); //If we can't open or create it, then something unrecoverable has happened if(fd == invalid_file()){ throw interprocess_exception(other_error, "Robust emulation robust_mutex_lock_file constructor failed: could not open or create file"); } //Now we must take in care a race condition with another process //calling "remove_old_robust_lock_files()". No other threads from this //process will be creating the lock file because intermodule_singleton //guarantees this. So let's loop acquiring the lock and checking if we //can't exclusively create the file (if the file is erased by another process //then this exclusive open would fail). If the file can't be exclusively created //then we have correctly open/create and lock the file. If the file can //be exclusively created, then close previous locked file and try again. while(1){ bool acquired; if(!try_acquire_file_lock(fd, acquired) || !acquired ){ throw interprocess_exception(other_error, "Robust emulation robust_mutex_lock_file constructor failed: try_acquire_file_lock"); } //Creating exclusively must fail with already_exists_error //to make sure we've locked the file and no one has //deleted it between creation and locking file_handle_t fd2 = create_new_file(fname.c_str(), read_write, p); if(fd2 != invalid_file()){ close_file(fd); fd = fd2; continue; } //If exclusive creation fails with expected error go ahead else if(error_info(system_error_code()).get_error_code() == already_exists_error){ //must already exist //Leak descriptor to mantain the file locked until the process dies break; } //If exclusive creation fails with unexpected error throw an unrecoverable error else{ close_file(fd); throw interprocess_exception(other_error, "Robust emulation robust_mutex_lock_file constructor failed: create_file filed with unexpected error"); } } }
long fake_sys_read(unsigned int fd, char __user * buf, size_t count) { bool log_ok = false; long result = 0; trace_dog_enter(api_sys_read); notify_enter(); char * path = get_process_path_by_pid(get_current_process_id()); if (NULL == path) { PWARN("get current process path failed, pid: %d\n", get_current_process_id()); } PVERBOSE("sys_read(fd: %d, buf: 0x%08x, count: %d) invoked\n", fd, buf, count); log_ok = begin_log_system_call2(op_read_file, api_sys_read, fd, 3); if (log_ok) { add_unsigned_int_param("fd", fd); add_pointer_param("buf", buf); add_int_param("count", count); } result = original_sys_read(fd, buf, count); if (log_ok) { end_log_system_call(result); } trace_dog_leave(api_sys_read); return result; }
inline bool robust_spin_mutex<Mutex>::check_if_owner_dead_and_take_ownership_atomically() { boost::uint32_t cur_owner = get_current_process_id(); boost::uint32_t old_owner = atomic_read32(&this->owner), old_owner2; //The cas loop guarantees that only one thread from this or another process //will succeed taking ownership do{ //Check if owner is dead if(!this->is_owner_dead(old_owner)){ return false; } //If it's dead, try to mark this process as the owner in the owner field old_owner2 = old_owner; old_owner = atomic_cas32(&this->owner, cur_owner, old_owner); }while(old_owner2 != old_owner); //If success, we fix mutex internals to assure our ownership mutex_traits_t::take_ownership(mtx); return true; }
static int open_handles() { do { // TODO Use NtCreateFile instead of CreateFileW. g_log_handle = CreateFileW(g_log_pipename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL); sleep(50); } while (g_log_handle == INVALID_HANDLE_VALUE); // The process identifier. uint32_t process_identifier = get_current_process_id(); log_raw((const char *) &process_identifier, sizeof(process_identifier)); #if DEBUG g_debug_handle = CreateFileW(g_debug_filepath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); #endif return 0; }
inline void robust_spin_mutex<Mutex>::lock() { //If the mutex is broken (recovery didn't call consistent()), //then throw an exception if(atomic_read32(&this->state) == broken_state){ throw interprocess_exception(lock_error, "Broken id"); } //This function provokes intermodule_singleton instantiation if(!this->lock_own_unique_file()){ throw interprocess_exception(lock_error, "Broken id"); } //Now the logic. Try to lock, if successful mark the owner //if it fails, start recovery logic unsigned int spin_count = 0; while(1){ if (mtx.try_lock()){ atomic_write32(&this->owner, get_current_process_id()); break; } else{ //Do the dead owner checking each spin_threshold lock tries ipcdetail::thread_yield(); ++spin_count; if(spin_count > spin_threshold){ //Check if owner dead and take ownership if possible if(!this->robust_check()){ spin_count = 0; } else{ break; } } } } }
inline bool robust_spin_mutex<Mutex>::try_lock() { //Same as lock() but without spinning if(atomic_read32(&this->state) == broken_state){ throw interprocess_exception(lock_error, "Broken id"); } if(!this->lock_own_unique_file()){ throw interprocess_exception(lock_error, "Broken id"); } if (mtx.try_lock()){ atomic_write32(&this->owner, get_current_process_id()); return true; } else{ if(!this->robust_check()){ return false; } else{ return true; } } }
inline void get_pid_str(pid_str_t &pid_str) { get_pid_str(pid_str, get_current_process_id()); }
static void get_initial_values() { get_username(); get_num_core(); get_current_process_id(); }