mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 02:42:44 +00:00 
			
		
		
		
	AK: Make MappedFile heap-allocated and ref-counted
Let's adapt this class a bit better to how it's actually being used. Instead of having valid/invalid states and storing an error in case it's invalid, a MappedFile is now always valid, and the factory function that creates it will return an OSError if mapping fails.
This commit is contained in:
		
							parent
							
								
									70fce5c4c7
								
							
						
					
					
						commit
						2f3b901f7f
					
				
					 36 changed files with 184 additions and 199 deletions
				
			
		|  | @ -1,5 +1,5 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> | ||||
|  * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org> | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  | @ -25,6 +25,7 @@ | |||
|  */ | ||||
| 
 | ||||
| #include <AK/MappedFile.h> | ||||
| #include <AK/ScopeGuard.h> | ||||
| #include <AK/String.h> | ||||
| #include <fcntl.h> | ||||
| #include <stdio.h> | ||||
|  | @ -32,68 +33,43 @@ | |||
| #include <sys/stat.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| //#define DEBUG_MAPPED_FILE
 | ||||
| 
 | ||||
| namespace AK { | ||||
| 
 | ||||
| MappedFile::MappedFile(const StringView& file_name) | ||||
| Result<NonnullRefPtr<MappedFile>, OSError> MappedFile::map(const StringView& path) | ||||
| { | ||||
|     int fd = open_with_path_length(file_name.characters_without_null_termination(), file_name.length(), O_RDONLY | O_CLOEXEC, 0); | ||||
|     int fd = open_with_path_length(path.characters_without_null_termination(), path.length(), O_RDONLY | O_CLOEXEC, 0); | ||||
|     if (fd < 0) | ||||
|         return OSError(errno); | ||||
| 
 | ||||
|     if (fd == -1) { | ||||
|         m_errno = errno; | ||||
|         perror("open"); | ||||
|         return; | ||||
|     } | ||||
|     ScopeGuard fd_close_guard = [fd] { | ||||
|         close(fd); | ||||
|     }; | ||||
| 
 | ||||
|     struct stat st; | ||||
|     fstat(fd, &st); | ||||
|     m_size = st.st_size; | ||||
|     m_map = mmap(nullptr, m_size, PROT_READ, MAP_SHARED, fd, 0); | ||||
| 
 | ||||
|     if (m_map == MAP_FAILED) { | ||||
|         m_errno = errno; | ||||
|         perror("mmap"); | ||||
|     if (fstat(fd, &st) < 0) { | ||||
|         auto saved_errno = errno; | ||||
|         return OSError(saved_errno); | ||||
|     } | ||||
| 
 | ||||
| #ifdef DEBUG_MAPPED_FILE | ||||
|     dbgln("MappedFile(\"{}\") := ( fd={}, m_size={}, m_map={} )", file_name, fd, m_size, m_map); | ||||
| #endif | ||||
|     auto size = st.st_size; | ||||
|     auto* ptr = mmap(nullptr, size, PROT_READ, MAP_SHARED, fd, 0); | ||||
| 
 | ||||
|     close(fd); | ||||
|     if (ptr == MAP_FAILED) | ||||
|         return OSError(errno); | ||||
| 
 | ||||
|     return adopt(*new MappedFile(ptr, size)); | ||||
| } | ||||
| 
 | ||||
| MappedFile::MappedFile(void* ptr, size_t size) | ||||
|     : m_data(ptr) | ||||
|     , m_size(size) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| MappedFile::~MappedFile() | ||||
| { | ||||
|     unmap(); | ||||
| } | ||||
| 
 | ||||
| void MappedFile::unmap() | ||||
| { | ||||
|     if (!is_valid()) | ||||
|         return; | ||||
|     int rc = munmap(m_map, m_size); | ||||
|     auto rc = munmap(m_data, m_size); | ||||
|     ASSERT(rc == 0); | ||||
|     m_size = 0; | ||||
|     m_map = (void*)-1; | ||||
| } | ||||
| 
 | ||||
| MappedFile::MappedFile(MappedFile&& other) | ||||
|     : m_size(other.m_size) | ||||
|     , m_map(other.m_map) | ||||
| { | ||||
|     other.m_size = 0; | ||||
|     other.m_map = (void*)-1; | ||||
| } | ||||
| 
 | ||||
| MappedFile& MappedFile::operator=(MappedFile&& other) | ||||
| { | ||||
|     if (this == &other) | ||||
|         return *this; | ||||
|     unmap(); | ||||
|     swap(m_size, other.m_size); | ||||
|     swap(m_map, other.m_map); | ||||
|     return *this; | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling