LogCabin
|
00001 /* Copyright (c) 2011-2014 Stanford University 00002 * Copyright (c) 2014-2015 Diego Ongaro 00003 * 00004 * Permission to use, copy, modify, and distribute this software for any 00005 * purpose with or without fee is hereby granted, provided that the above 00006 * copyright notice and this permission notice appear in all copies. 00007 * 00008 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES 00009 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 00010 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR 00011 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 00012 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 00013 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 00014 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 00015 */ 00016 00017 #include <cstring> 00018 #include <sys/epoll.h> 00019 #include <unistd.h> 00020 00021 #include "Core/Debug.h" 00022 #include "Event/File.h" 00023 #include "Event/Loop.h" 00024 00025 namespace LogCabin { 00026 namespace Event { 00027 00028 //// class File::Monitor //// 00029 00030 File::Monitor::Monitor(Event::Loop& eventLoop, File& file, uint32_t fileEvents) 00031 : eventLoop(eventLoop) 00032 , mutex() 00033 , file(&file) 00034 { 00035 struct epoll_event event; 00036 memset(&event, 0, sizeof(event)); 00037 event.events = fileEvents; 00038 event.data.ptr = this->file; 00039 int r = epoll_ctl(eventLoop.epollfd, EPOLL_CTL_ADD, 00040 this->file->fd, &event); 00041 if (r != 0) { 00042 PANIC("Adding file %d event with epoll_ctl failed: %s", 00043 this->file->fd, strerror(errno)); 00044 } 00045 } 00046 00047 File::Monitor::~Monitor() 00048 { 00049 disableForever(); 00050 } 00051 00052 void 00053 File::Monitor::disableForever() 00054 { 00055 std::lock_guard<std::mutex> mutexGuard(mutex); 00056 if (file == NULL) 00057 return; 00058 Event::Loop::Lock lock(eventLoop); 00059 int r = epoll_ctl(eventLoop.epollfd, EPOLL_CTL_DEL, file->fd, NULL); 00060 if (r != 0) { 00061 PANIC("Removing file %d event with epoll_ctl failed: %s", 00062 file->fd, strerror(errno)); 00063 } 00064 file = NULL; 00065 } 00066 00067 void 00068 File::Monitor::setEvents(uint32_t fileEvents) 00069 { 00070 std::lock_guard<std::mutex> mutexGuard(mutex); 00071 if (file == NULL) 00072 return; 00073 struct epoll_event event; 00074 memset(&event, 0, sizeof(event)); 00075 event.events = fileEvents; 00076 event.data.ptr = file; 00077 int r = epoll_ctl(eventLoop.epollfd, EPOLL_CTL_MOD, file->fd, &event); 00078 if (r != 0) { 00079 PANIC("Modifying file %d event with epoll_ctl failed: %s", 00080 file->fd, strerror(errno)); 00081 } 00082 } 00083 00084 //// class File //// 00085 00086 File::File(int fd, Ownership ownership) 00087 : fd(fd) 00088 , ownership(ownership) 00089 { 00090 } 00091 00092 File::~File() 00093 { 00094 if (ownership == CLOSE_ON_DESTROY) { 00095 int r = close(fd); 00096 if (r != 0) 00097 PANIC("Could not close file %d: %s", fd, strerror(errno)); 00098 } 00099 } 00100 00101 } // namespace LogCabin::Event 00102 } // namespace LogCabin