LogCabin
Event/File.cc
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines