修复文件映射内存使用问题,补充win平台功能
This commit is contained in:
parent
1539a698b1
commit
5943ee86d6
|
@ -346,141 +346,183 @@ int shared_memory::write(const char* data, size_t len)
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// tiny_file_map ...
|
// tiny_file_map ...
|
||||||
#ifdef WIN32
|
tiny_file_map::tiny_file_map() : size_(0), map_(INVALID_HANDLE_NAME), buf_(nullptr), file_(""), keep_f_(false)
|
||||||
#define IS_VALID_MAP(map) map
|
, map_off_(0), map_bytes_(0), page_size_(hg_log::get_page_size())
|
||||||
#else
|
|
||||||
#define IS_VALID_MAP(map) map != -1
|
|
||||||
#endif
|
|
||||||
tiny_file_map::tiny_file_map() : size_(0), map_(0), buf_(nullptr), file_(""), keep_f_(false)
|
|
||||||
{}
|
{}
|
||||||
tiny_file_map::~tiny_file_map()
|
tiny_file_map::~tiny_file_map()
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
int tiny_file_map::open(const char* file, unsigned int size, bool readonly)
|
HANDLE_NAME tiny_file_map::open_file_for_mapping(const char* file, unsigned* bytes, bool create)
|
||||||
{
|
{
|
||||||
close();
|
HANDLE_NAME ret = INVALID_HANDLE_NAME;
|
||||||
|
|
||||||
int ret = 0;
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if (readonly)
|
HANDLE f = INVALID_HANDLE_VALUE;
|
||||||
|
if (create)
|
||||||
{
|
{
|
||||||
HANDLE f = CreateFileA(file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
f = CreateFileA(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
if (f == INVALID_HANDLE_VALUE)
|
if (f != INVALID_HANDLE_VALUE)
|
||||||
ret = GetLastError();
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
size_ = GetFileSize(f, NULL);
|
DWORD wrote = SetFilePointer(f, *bytes - 1, NULL, FILE_BEGIN);
|
||||||
map_ = CreateFileMappingA(f, NULL, PAGE_READONLY, 0, 0, NULL);
|
if (wrote != *bytes - 1 || !WriteFile(f, "\0", 1, &wrote, NULL))
|
||||||
if (map_)
|
|
||||||
{
|
{
|
||||||
buf_ = (unsigned char*)MapViewOfFile(map_, FILE_MAP_READ, 0, 0, 0);
|
CloseHandle(f);
|
||||||
if (!buf_)
|
f = INVALID_HANDLE_VALUE;
|
||||||
{
|
}
|
||||||
ret = GetLastError();
|
|
||||||
CloseHandle(map_);
|
|
||||||
map_ = nullptr;
|
|
||||||
size_ = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ret = GetLastError();
|
{
|
||||||
|
f = CreateFileA(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (f != INVALID_HANDLE_VALUE)
|
||||||
|
*bytes = GetFileSize(f, NULL);
|
||||||
|
}
|
||||||
|
if (f != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
ret = CreateFileMapping(f, NULL, PAGE_READWRITE, 0, *bytes, NULL);
|
||||||
CloseHandle(f);
|
CloseHandle(f);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if (create)
|
||||||
|
{
|
||||||
|
ret = ::open(file, O_CREAT | O_RDWR);
|
||||||
|
if (ret != INVALID_HANDLE_NAME)
|
||||||
|
{
|
||||||
|
if (lseek(ret, *bytes - 1, SEEK_SET) < 0)
|
||||||
|
{
|
||||||
|
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "set file size to %u - 1 bytes failed: %d\n", *bytes, errno);
|
||||||
|
::close(ret);
|
||||||
|
remove(file);
|
||||||
|
ret = INVALID_HANDLE_NAME;
|
||||||
|
}
|
||||||
|
if (write(ret, "0", 1) < 0)
|
||||||
|
{
|
||||||
|
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "set file size to %u bytes failed: %d\n", *bytes, errno);
|
||||||
|
::close(ret);
|
||||||
|
remove(file);
|
||||||
|
ret = INVALID_HANDLE_NAME;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_ = size;
|
ret = ::open(file, O_RDWR);
|
||||||
|
if (ret != INVALID_HANDLE_NAME)
|
||||||
|
{
|
||||||
|
struct stat fsize;
|
||||||
|
if (fstat(ret, &fsize) >= 0)
|
||||||
|
*bytes = fsize.st_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
HANDLE f = CreateFileA(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
return ret;
|
||||||
if (f == INVALID_HANDLE_VALUE)
|
}
|
||||||
ret = GetLastError();
|
void tiny_file_map::close_handle_name(HANDLE_NAME h)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
CloseHandle(h);
|
||||||
|
#else
|
||||||
|
::close(h);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void* tiny_file_map::sys_map_api(HANDLE_NAME h, int access, unsigned int off, unsigned size, int* err)
|
||||||
|
{
|
||||||
|
void* mem = nullptr;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
mem = MapViewOfFile(h, access, 0, off, size);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
if (mem)
|
||||||
|
*err = SCANNER_ERR_OK;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//SYSTEM_INFO si = { 0 };
|
if (GetLastError() == ERROR_NOT_ENOUGH_MEMORY)
|
||||||
//GetSystemInfo(&si);
|
*err = SCANNER_ERR_INSUFFICIENT_MEMORY;
|
||||||
//size += si.dwPageSize - 1;
|
|
||||||
//size /= si.dwPageSize;
|
|
||||||
//size *= si.dwPageSize;
|
|
||||||
DWORD wrote = SetFilePointer(f, size - 1, NULL, FILE_BEGIN);
|
|
||||||
if (wrote == size - 1)
|
|
||||||
WriteFile(f, "\0", 1, &wrote, NULL);
|
|
||||||
map_ = CreateFileMappingA(f, NULL, PAGE_READWRITE, 0, size, NULL);
|
|
||||||
if (map_)
|
|
||||||
{
|
|
||||||
buf_ = (unsigned char*)MapViewOfFile(map_, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, size);
|
|
||||||
if (!buf_)
|
|
||||||
ret = GetLastError();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
ret = GetLastError();
|
*err = SCANNER_ERR_OUT_OF_RANGE;
|
||||||
CloseHandle(f);
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
keep_f_ = false;
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (readonly)
|
mem = mmap(nullptr, size, access, MAP_SHARED, h, off);
|
||||||
|
if (mem == MAP_FAILED)
|
||||||
{
|
{
|
||||||
map_ = ::open(file, O_RDONLY);
|
mem = nullptr;
|
||||||
if (IS_VALID_MAP(map_))
|
if (errno == ENOMEM)
|
||||||
{
|
*err = SCANNER_ERR_INSUFFICIENT_MEMORY;
|
||||||
struct stat fsize;
|
|
||||||
if (fstat(map_, &fsize) >= 0)
|
|
||||||
size_ = size = fsize.st_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
*err = SCANNER_ERR_OUT_OF_RANGE;
|
||||||
map_ = ::open(file, O_CREAT | O_RDWR);
|
|
||||||
if (IS_VALID_MAP(map_))
|
|
||||||
{
|
|
||||||
if (lseek(map_, size - 1, SEEK_SET) < 0)
|
|
||||||
{
|
|
||||||
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "set file size to %u - 1 bytes failed: %d\n", size, errno);
|
|
||||||
ret = errno;
|
|
||||||
::close(map_);
|
|
||||||
map_ = 0;
|
|
||||||
remove(file);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
if (write(map_, "0", 1) < 0)
|
else if(err)
|
||||||
{
|
*err = SCANNER_ERR_OK;
|
||||||
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "set file size to %u bytes failed: %d\n", size, errno);
|
|
||||||
ret = errno;
|
|
||||||
::close(map_);
|
|
||||||
map_ = 0;
|
|
||||||
remove(file);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (IS_VALID_MAP(map_))
|
|
||||||
{
|
|
||||||
buf_ = (unsigned char*)mmap(nullptr, size, readonly ? PROT_READ : PROT_WRITE, MAP_SHARED, map_, 0);
|
|
||||||
if (buf_ == (unsigned char*)MAP_FAILED)
|
|
||||||
{
|
|
||||||
buf_ = nullptr;
|
|
||||||
ret = errno;
|
|
||||||
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "mmap(%u) = %d\n", size, ret);
|
|
||||||
size_ = 0;
|
|
||||||
if (!readonly)
|
|
||||||
remove(file);
|
|
||||||
}
|
|
||||||
::close(map_);
|
|
||||||
map_ = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ret = errno;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
void tiny_file_map::sys_unmap_api(void* buf, size_t size)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
UnmapViewOfFile(buf);
|
||||||
|
#else
|
||||||
|
munmap(buf, size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "map([%s]%s) = %d\n", readonly ? "R" : "RW", file, ret);
|
int tiny_file_map::map_to_mem(unsigned int off)
|
||||||
if (ret == 0)
|
{
|
||||||
|
int err = SCANNER_ERR_OUT_OF_RANGE;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
int acc = FILE_MAP_READ | FILE_MAP_WRITE;
|
||||||
|
#else
|
||||||
|
int acc = PROT_READ | PROT_WRITE;
|
||||||
|
#endif
|
||||||
|
if (off < size_)
|
||||||
|
{
|
||||||
|
unsigned int bytes = size_ - off;
|
||||||
|
if (off >= map_off_ && off + bytes <= map_off_ + map_bytes_)
|
||||||
|
err = SCANNER_ERR_OK;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (buf_)
|
||||||
|
tiny_file_map::sys_unmap_api(buf_, map_bytes_);
|
||||||
|
off /= page_size_;
|
||||||
|
off *= page_size_;
|
||||||
|
map_bytes_ = bytes;
|
||||||
|
map_off_ = off;
|
||||||
|
buf_ = (unsigned char*)tiny_file_map::sys_map_api(map_, acc, map_off_, map_bytes_, &err); // MapViewOfFile(map_, FILE_MAP_READ | FILE_MAP_WRITE, 0, off, map_bytes_);
|
||||||
|
if (err != SCANNER_ERR_OK)
|
||||||
|
{
|
||||||
|
map_bytes_ /= page_size_;
|
||||||
|
map_bytes_ *= page_size_;
|
||||||
|
while (map_bytes_ >= page_size_
|
||||||
|
&& !(buf_ = (unsigned char*)tiny_file_map::sys_map_api(map_, acc, map_off_, map_bytes_, &err))
|
||||||
|
&& err == SCANNER_ERR_INSUFFICIENT_MEMORY)
|
||||||
|
map_bytes_ -= page_size_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tiny_file_map::open(const char* file, bool existing, unsigned int size)
|
||||||
|
{
|
||||||
|
int ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
|
||||||
|
|
||||||
|
close();
|
||||||
|
map_ = tiny_file_map::open_file_for_mapping(file, &size, !existing);
|
||||||
|
if (map_ != INVALID_HANDLE_NAME)
|
||||||
|
{
|
||||||
|
ret = SCANNER_ERR_OK;
|
||||||
|
size_ = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "map([%s]%s) = %d\n", existing ? "existing" : "new", file, ret);
|
||||||
|
if (ret == SCANNER_ERR_OK)
|
||||||
file_ = file;
|
file_ = file;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -489,21 +531,13 @@ void tiny_file_map::close(void)
|
||||||
{
|
{
|
||||||
if (buf_)
|
if (buf_)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
tiny_file_map::sys_unmap_api(buf_, size_);
|
||||||
UnmapViewOfFile(buf_);
|
|
||||||
#else
|
|
||||||
munmap(buf_, size_);
|
|
||||||
#endif
|
|
||||||
buf_ = nullptr;
|
buf_ = nullptr;
|
||||||
}
|
}
|
||||||
if (map_)
|
if (map_ != INVALID_HANDLE_NAME)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
close_handle_name(map_);
|
||||||
CloseHandle(map_);
|
map_ = INVALID_HANDLE_NAME;
|
||||||
#else
|
|
||||||
::close(map_);
|
|
||||||
#endif
|
|
||||||
map_ = 0;
|
|
||||||
}
|
}
|
||||||
if (!keep_f_ && !file_.empty())
|
if (!keep_f_ && !file_.empty())
|
||||||
remove(file_.c_str());
|
remove(file_.c_str());
|
||||||
|
@ -511,14 +545,51 @@ void tiny_file_map::close(void)
|
||||||
size_ = 0;
|
size_ = 0;
|
||||||
file_ = "";
|
file_ = "";
|
||||||
keep_f_ = false;
|
keep_f_ = false;
|
||||||
|
map_off_ = map_bytes_ = 0;
|
||||||
}
|
}
|
||||||
void tiny_file_map::keep_file(bool keep)
|
void tiny_file_map::keep_file(bool keep)
|
||||||
{
|
{
|
||||||
keep_f_ = keep;
|
keep_f_ = keep;
|
||||||
}
|
}
|
||||||
unsigned char* tiny_file_map::mapping_buffer(void)
|
unsigned char* tiny_file_map::mapping_buffer(unsigned int off, unsigned int* bytes)
|
||||||
{
|
{
|
||||||
return buf_;
|
unsigned int len = bytes ? *bytes : size_;
|
||||||
|
unsigned char* buf = nullptr;
|
||||||
|
|
||||||
|
if (off >= size_)
|
||||||
|
{
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
if (!buf_ && map_to_mem(off) != SCANNER_ERR_OK)
|
||||||
|
{
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (off >= map_off_ && off + len <= map_off_ + map_bytes_)
|
||||||
|
{
|
||||||
|
buf = buf_ + off - map_off_;
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (off < map_off_ || off >= map_off_ + map_bytes_)
|
||||||
|
{
|
||||||
|
if (map_to_mem(off) == SCANNER_ERR_OK)
|
||||||
|
{
|
||||||
|
buf = buf_ + off - map_off_;
|
||||||
|
if (bytes)
|
||||||
|
*bytes = map_bytes_ - (off - map_off_);
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
buf = buf_ + off - map_off_;
|
||||||
|
if (bytes)
|
||||||
|
*bytes = map_bytes_ - (off - map_off_);
|
||||||
|
|
||||||
|
return buf;
|
||||||
}
|
}
|
||||||
std::string tiny_file_map::file(void)
|
std::string tiny_file_map::file(void)
|
||||||
{
|
{
|
||||||
|
@ -533,34 +604,8 @@ bool tiny_file_map::swap(void)
|
||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
if (buf_)
|
tiny_file_map::sys_unmap_api(buf_, size_);
|
||||||
{
|
|
||||||
#ifdef WIN32
|
|
||||||
UnmapViewOfFile(buf_);
|
|
||||||
#else
|
|
||||||
munmap(buf_, size_);
|
|
||||||
#endif
|
|
||||||
buf_ = nullptr;
|
buf_ = nullptr;
|
||||||
}
|
|
||||||
else if (IS_VALID_MAP(map_))
|
|
||||||
{
|
|
||||||
#ifdef WIN32
|
|
||||||
buf_ = (unsigned char*)MapViewOfFile(map_, FILE_MAP_READ, 0, 0, size_);
|
|
||||||
#else
|
|
||||||
buf_ = (unsigned char*)mmap(nullptr, size_, PROT_READ, MAP_PRIVATE, map_, 0);
|
|
||||||
if (buf_ == (unsigned char*)MAP_FAILED)
|
|
||||||
{
|
|
||||||
buf_ == nullptr;
|
|
||||||
VLOG_MINI_2(LOG_LEVEL_FATAL, "Remap '%s' failed: %d\n", file_.c_str(), errno);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
ret = buf_ != nullptr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
VLOG_MINI_2(LOG_LEVEL_FATAL, "Remap '%s' bug the handle is %d\n", file_.c_str(), map_);
|
|
||||||
ret = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -576,11 +621,13 @@ tiny_buffer::tiny_buffer(unsigned int size
|
||||||
{
|
{
|
||||||
init(tmp_path, name_leading, ext, uniq_id);
|
init(tmp_path, name_leading, ext, uniq_id);
|
||||||
}
|
}
|
||||||
tiny_buffer::tiny_buffer(const char* src_file)
|
tiny_buffer::tiny_buffer(const char* src_file) : size_(0), buf_(nullptr)
|
||||||
{
|
{
|
||||||
fmap_.open(src_file, 0, true);
|
fmap_.open(src_file);
|
||||||
buf_ = fmap_.mapping_buffer();
|
|
||||||
size_ = fmap_.size();
|
size_ = fmap_.size();
|
||||||
|
|
||||||
|
unsigned int len = size_;
|
||||||
|
buf_ = fmap_.mapping_buffer(0, &len);
|
||||||
}
|
}
|
||||||
tiny_buffer::~tiny_buffer()
|
tiny_buffer::~tiny_buffer()
|
||||||
{
|
{
|
||||||
|
@ -601,6 +648,8 @@ void tiny_buffer::init(const char* tmp_path, const char* name_leading, const cha
|
||||||
memset(buf_, 0, size_);
|
memset(buf_, 0, size_);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
|
{
|
||||||
|
if (tmp_path && *tmp_path)
|
||||||
{
|
{
|
||||||
std::string f(tmp_path);
|
std::string f(tmp_path);
|
||||||
char buf[128] = { 0 };
|
char buf[128] = { 0 };
|
||||||
|
@ -610,20 +659,31 @@ void tiny_buffer::init(const char* tmp_path, const char* name_leading, const cha
|
||||||
sprintf(buf, "_%05u.%s", uniq_id, ext ? ext : "tmp");
|
sprintf(buf, "_%05u.%s", uniq_id, ext ? ext : "tmp");
|
||||||
f += buf;
|
f += buf;
|
||||||
|
|
||||||
|
unsigned int bytes = size_;
|
||||||
fmap_.open(f.c_str(), size_, false);
|
fmap_.open(f.c_str(), size_, false);
|
||||||
buf_ = fmap_.mapping_buffer();
|
buf_ = fmap_.mapping_buffer(0, &bytes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "Acquire memory with bytes %u = %s\n", size_, hg_log::format_ptr(buf_).c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int tiny_buffer::size(void)
|
unsigned int tiny_buffer::size(void)
|
||||||
{
|
{
|
||||||
return size_;
|
return size_;
|
||||||
}
|
}
|
||||||
unsigned char* tiny_buffer::data(void)
|
unsigned char* tiny_buffer::data(unsigned int off, unsigned int* bytes)
|
||||||
{
|
{
|
||||||
return buf_;
|
if (off >= size_)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (fmap_.file().empty())
|
||||||
|
{
|
||||||
|
if (size_ - off < *bytes)
|
||||||
|
*bytes = size_ - off;
|
||||||
|
|
||||||
|
return buf_ + off;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmap_.mapping_buffer(off, bytes);
|
||||||
}
|
}
|
||||||
void tiny_buffer::keep_file(bool keep)
|
void tiny_buffer::keep_file(bool keep)
|
||||||
{
|
{
|
||||||
|
@ -640,8 +700,9 @@ bool tiny_buffer::swap(void)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
bool ret = fmap_.swap();
|
bool ret = fmap_.swap();
|
||||||
|
unsigned int bytes = size_;
|
||||||
|
|
||||||
buf_ = fmap_.mapping_buffer();
|
buf_ = fmap_.mapping_buffer(0, &bytes);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -672,6 +733,7 @@ bool final_img_queue::put(int w, int h, int bpp, int channels, int line_bytes, v
|
||||||
{
|
{
|
||||||
IMGDT imgd;
|
IMGDT imgd;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
unsigned int l = bytes, off = 0;
|
||||||
|
|
||||||
imgd.header.bits = bpp;
|
imgd.header.bits = bpp;
|
||||||
imgd.header.bytes = bytes;
|
imgd.header.bytes = bytes;
|
||||||
|
@ -681,10 +743,21 @@ bool final_img_queue::put(int w, int h, int bpp, int channels, int line_bytes, v
|
||||||
imgd.header.width = w;
|
imgd.header.width = w;
|
||||||
imgd.offset = 0;
|
imgd.offset = 0;
|
||||||
imgd.data.reset(new tiny_buffer(bytes, tmp_path, name_leading, ext, ind));
|
imgd.data.reset(new tiny_buffer(bytes, tmp_path, name_leading, ext, ind));
|
||||||
if(imgd.data->data())
|
|
||||||
|
unsigned char* buf = imgd.data->data(off, &l),
|
||||||
|
* src = (unsigned char*)data;
|
||||||
|
while(buf)
|
||||||
{
|
{
|
||||||
memcpy(imgd.data->data(), data, bytes);
|
memcpy(buf, src, l);
|
||||||
if (imgd.data->swap())
|
off += l;
|
||||||
|
if (off >= bytes)
|
||||||
|
break;
|
||||||
|
|
||||||
|
src += l;
|
||||||
|
l = bytes - off;
|
||||||
|
buf = imgd.data->data(off, &l);
|
||||||
|
}
|
||||||
|
if (off >= bytes && imgd.data->swap())
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lck(lock_);
|
std::lock_guard<std::mutex> lck(lock_);
|
||||||
queue_.push_back(imgd);
|
queue_.push_back(imgd);
|
||||||
|
@ -692,7 +765,6 @@ bool final_img_queue::put(int w, int h, int bpp, int channels, int line_bytes, v
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
imgd.data.reset();
|
imgd.data.reset();
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -719,24 +791,29 @@ void final_img_queue::fetch_front(void* buf, int* len, bool* over)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// for third-apps, we make fake data upto len when re-map file failed here
|
||||||
IMGDT& imgd = queue_[0];
|
IMGDT& imgd = queue_[0];
|
||||||
|
|
||||||
if (imgd.offset == 0)
|
if (imgd.offset == 0)
|
||||||
{
|
{
|
||||||
if (!imgd.data->swap())
|
if (!imgd.data->swap())
|
||||||
{
|
{
|
||||||
*len = 0;
|
|
||||||
if (over)
|
|
||||||
*over = true;
|
|
||||||
|
|
||||||
VLOG_MINI_1(LOG_LEVEL_FATAL, "Reload final image '%s' failed!\n", imgd.data->file().c_str());
|
VLOG_MINI_1(LOG_LEVEL_FATAL, "Reload final image '%s' failed!\n", imgd.data->file().c_str());
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imgd.offset + *len >= imgd.header.bytes)
|
if (imgd.offset + *len >= imgd.header.bytes)
|
||||||
*len = imgd.header.bytes - imgd.offset;
|
*len = imgd.header.bytes - imgd.offset;
|
||||||
memcpy(buf, imgd.data->data() + imgd.offset, *len);
|
|
||||||
|
unsigned char* src = imgd.data->data(imgd.offset, (unsigned int*)len);
|
||||||
|
if (src)
|
||||||
|
{
|
||||||
|
memcpy(buf, src, *len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VLOG_MINI_2(LOG_LEVEL_FATAL, "Remap final image '%s + 0x%08x' failed!\n", imgd.data->file().c_str(), imgd.offset);
|
||||||
|
}
|
||||||
imgd.offset += *len;
|
imgd.offset += *len;
|
||||||
if (imgd.offset >= imgd.header.bytes)
|
if (imgd.offset >= imgd.header.bytes)
|
||||||
{
|
{
|
||||||
|
|
|
@ -131,27 +131,40 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// buffer
|
// buffer
|
||||||
|
#ifdef WIN32
|
||||||
|
#define HANDLE_NAME HANDLE
|
||||||
|
#define INVALID_HANDLE_NAME NULL
|
||||||
|
#else
|
||||||
|
#define HANDLE_NAME int
|
||||||
|
#define INVALID_HANDLE_NAME -1
|
||||||
|
#endif
|
||||||
class tiny_file_map
|
class tiny_file_map
|
||||||
{
|
{
|
||||||
unsigned int size_;
|
unsigned int size_;
|
||||||
#ifdef WIN32
|
unsigned int page_size_;
|
||||||
HANDLE map_;
|
HANDLE_NAME map_;
|
||||||
#else
|
|
||||||
int map_;
|
|
||||||
#endif
|
|
||||||
unsigned char *buf_;
|
unsigned char *buf_;
|
||||||
std::string file_;
|
std::string file_;
|
||||||
bool keep_f_;
|
bool keep_f_;
|
||||||
|
unsigned int map_off_;
|
||||||
|
unsigned int map_bytes_;
|
||||||
|
|
||||||
|
int map_to_mem(unsigned int off = 0);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
tiny_file_map();
|
tiny_file_map();
|
||||||
~tiny_file_map();
|
~tiny_file_map();
|
||||||
|
|
||||||
|
static HANDLE_NAME open_file_for_mapping(const char* file, unsigned* bytes, bool create);
|
||||||
|
static void close_handle_name(HANDLE_NAME h);
|
||||||
|
static void* sys_map_api(HANDLE_NAME h, int access, unsigned int off, unsigned size, int* err);
|
||||||
|
static void sys_unmap_api(void* buf, size_t size = 0);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int open(const char* file, unsigned int size, bool readonly);
|
int open(const char* file, bool existing = true, unsigned int size = 0);
|
||||||
void close(void);
|
void close(void);
|
||||||
void keep_file(bool keep);
|
void keep_file(bool keep);
|
||||||
unsigned char* mapping_buffer(void);
|
unsigned char* mapping_buffer(unsigned int off, unsigned int* bytes);
|
||||||
std::string file(void);
|
std::string file(void);
|
||||||
unsigned int size(void);
|
unsigned int size(void);
|
||||||
|
|
||||||
|
@ -173,7 +186,7 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned int size(void);
|
unsigned int size(void);
|
||||||
unsigned char* data(void);
|
unsigned char* data(unsigned int off, unsigned int* bytes/*[in] - need bytes, [out] - real bytes*/);
|
||||||
void keep_file(bool keep);
|
void keep_file(bool keep);
|
||||||
std::string file(void);
|
std::string file(void);
|
||||||
|
|
||||||
|
|
|
@ -95,11 +95,17 @@ hg_scanner::hg_scanner(ScannerSerial serial
|
||||||
{
|
{
|
||||||
final_path_ = hg_log::ini_get("paths", "final_img");
|
final_path_ = hg_log::ini_get("paths", "final_img");
|
||||||
if(final_path_.empty())
|
if(final_path_.empty())
|
||||||
final_path_ = hg_log::get_scanner_path() + "imgs";
|
final_path_ = hg_log::local_data_path() + PATH_SEPARATOR + "imgs";
|
||||||
if (hg_log::create_folder(final_path_.c_str()))
|
if (hg_log::create_folder(final_path_.c_str()))
|
||||||
|
{
|
||||||
|
VLOG_MINI_1(LOG_LEVEL_WARNING, "temporary image folder: %s\n", final_path_.c_str());
|
||||||
final_path_ += PATH_SEPARATOR;
|
final_path_ += PATH_SEPARATOR;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
VLOG_MINI_1(LOG_LEVEL_WARNING, "create temporary image folder failed: %s\n", final_path_.c_str());
|
||||||
final_path_ = "";
|
final_path_ = "";
|
||||||
|
}
|
||||||
|
|
||||||
custom_gamma_val_ = new SANE_Gamma;
|
custom_gamma_val_ = new SANE_Gamma;
|
||||||
memset(custom_gamma_val_, 0, sizeof(SANE_Gamma));
|
memset(custom_gamma_val_, 0, sizeof(SANE_Gamma));
|
||||||
|
@ -1694,7 +1700,7 @@ std::shared_ptr<tiny_buffer> hg_scanner::aquire_memory(int size, bool from_usb)
|
||||||
unsigned int ind = from_usb ? usb_img_index_ : final_img_index_;
|
unsigned int ind = from_usb ? usb_img_index_ : final_img_index_;
|
||||||
std::shared_ptr<tiny_buffer> mem(new tiny_buffer(size, final_path_.c_str(), lead.c_str(), ext.c_str(), ind));
|
std::shared_ptr<tiny_buffer> mem(new tiny_buffer(size, final_path_.c_str(), lead.c_str(), ext.c_str(), ind));
|
||||||
|
|
||||||
if (!mem->data())
|
if (!mem->data(0, (unsigned int*)&size))
|
||||||
{
|
{
|
||||||
mem.reset();
|
mem.reset();
|
||||||
LOG_INFO(LOG_LEVEL_FATAL, "Can't aquire enough memory, working must be stopped!\n");
|
LOG_INFO(LOG_LEVEL_FATAL, "Can't aquire enough memory, working must be stopped!\n");
|
||||||
|
|
|
@ -573,7 +573,16 @@ int hg_scanner_200::get_img_data(unsigned int bytes)
|
||||||
if (total < block)
|
if (total < block)
|
||||||
block = total;
|
block = total;
|
||||||
|
|
||||||
ret = io_->read_bulk(imagedata->data() + index, &block);
|
unsigned int size = block;
|
||||||
|
void* buf = imagedata->data(index, &size);
|
||||||
|
if (!buf)
|
||||||
|
{
|
||||||
|
VLOG_MINI_3(LOG_LEVEL_FATAL, "memory(0x%08x + %u) fatal when read USB image %d !!!\n", index, block, usb_img_index_);
|
||||||
|
ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
block = size;
|
||||||
|
ret = io_->read_bulk(buf, &block);
|
||||||
io_->set_timeout(500); //不能删除可能会导致IO超时
|
io_->set_timeout(500); //不能删除可能会导致IO超时
|
||||||
if (ret != SCANNER_ERR_OK)
|
if (ret != SCANNER_ERR_OK)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1020,7 +1020,17 @@ int hg_scanner_239::read_one_image_from_usb(void)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(io_lock_);
|
std::lock_guard<std::mutex> lock(io_lock_);
|
||||||
|
|
||||||
ret = io_->read_bulk(buf->data(), &r);
|
unsigned int size = r;
|
||||||
|
void* buff = buf->data(off, &size);
|
||||||
|
if (!buff)
|
||||||
|
{
|
||||||
|
VLOG_MINI_3(LOG_LEVEL_FATAL, "memory(0x%08x + %u) fatal when read USB image %d !!!\n", off, r, usb_img_index_);
|
||||||
|
ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = size;
|
||||||
|
ret = io_->read_bulk(buff, &r);
|
||||||
|
|
||||||
while (ret == SCANNER_ERR_OK)
|
while (ret == SCANNER_ERR_OK)
|
||||||
{
|
{
|
||||||
|
@ -1029,7 +1039,17 @@ int hg_scanner_239::read_one_image_from_usb(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
r = total - off;
|
r = total - off;
|
||||||
ret = io_->read_bulk(buf->data() + off, &r);
|
size = r;
|
||||||
|
buff = buf->data(off, &size);
|
||||||
|
if (!buff)
|
||||||
|
{
|
||||||
|
VLOG_MINI_3(LOG_LEVEL_FATAL, "memory(0x%08x + %u) fatal when read USB image %d !!!\n", off, r, usb_img_index_);
|
||||||
|
ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
r = size;
|
||||||
|
ret = io_->read_bulk(buff, &r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret == SCANNER_ERR_OK)
|
if (ret == SCANNER_ERR_OK)
|
||||||
|
@ -1179,6 +1199,7 @@ int hg_scanner_239::on_color_mode_changed(int& color_mode)
|
||||||
{
|
{
|
||||||
dev_conf_.g200params.color = 1;
|
dev_conf_.g200params.color = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
HGSCANCONF d = dev_conf_;
|
HGSCANCONF d = dev_conf_;
|
||||||
|
|
||||||
if (image_prc_param_.bits.rid_color != RID_COLOR_NONE
|
if (image_prc_param_.bits.rid_color != RID_COLOR_NONE
|
||||||
|
@ -1203,6 +1224,7 @@ int hg_scanner_239::on_color_mode_changed(int& color_mode)
|
||||||
}
|
}
|
||||||
if(color_mode == -1)
|
if(color_mode == -1)
|
||||||
ret = writedown_device_configuration(&d);
|
ret = writedown_device_configuration(&d);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
int hg_scanner_239::on_paper_changed(int& paper)
|
int hg_scanner_239::on_paper_changed(int& paper)
|
||||||
|
|
|
@ -516,7 +516,16 @@ int hg_scanner_300::get_img_data(std::shared_ptr<tiny_buffer> &imagedata)
|
||||||
if (total < block)
|
if (total < block)
|
||||||
block = total;
|
block = total;
|
||||||
|
|
||||||
ret = io_->read_bulk(imagedata->data() + index,&block);
|
unsigned int size = block;
|
||||||
|
void* buf = imagedata->data(index, &size);
|
||||||
|
if (!buf)
|
||||||
|
{
|
||||||
|
VLOG_MINI_3(LOG_LEVEL_FATAL, "memory(0x%08x + %u) fatal when read USB image %d !!!\n", index, block, usb_img_index_);
|
||||||
|
ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
block = size;
|
||||||
|
ret = io_->read_bulk(buf, &block);
|
||||||
|
|
||||||
if (ret != SCANNER_ERR_OK)
|
if (ret != SCANNER_ERR_OK)
|
||||||
{
|
{
|
||||||
|
|
|
@ -516,7 +516,16 @@ int hg_scanner_400::get_img_data(std::shared_ptr<tiny_buffer> &imagedata)
|
||||||
if (total < block)
|
if (total < block)
|
||||||
block = total;
|
block = total;
|
||||||
|
|
||||||
ret = io_->read_bulk(imagedata->data() + index,&block);
|
unsigned int size = block;
|
||||||
|
void* buf = imagedata->data(index, &size);
|
||||||
|
if (!buf)
|
||||||
|
{
|
||||||
|
VLOG_MINI_3(LOG_LEVEL_FATAL, "memory(0x%08x + %u) fatal when read USB image %d !!!\n", index, block, usb_img_index_);
|
||||||
|
ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
block = size;
|
||||||
|
ret = io_->read_bulk(buf, &block);
|
||||||
|
|
||||||
if (ret != SCANNER_ERR_OK)
|
if (ret != SCANNER_ERR_OK)
|
||||||
{
|
{
|
||||||
|
|
|
@ -87,11 +87,31 @@ namespace hg_imgproc
|
||||||
public:
|
public:
|
||||||
int load_raw_data(std::shared_ptr<tiny_buffer> buff)
|
int load_raw_data(std::shared_ptr<tiny_buffer> buff)
|
||||||
{
|
{
|
||||||
|
int ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
|
||||||
|
|
||||||
buffer_.reset(new std::vector<char>(buff->size()));
|
buffer_.reset(new std::vector<char>(buff->size()));
|
||||||
if (buffer_.get())
|
if (buffer_.get())
|
||||||
memcpy(buffer_->data(), buff->data(), buff->size());
|
{
|
||||||
|
unsigned int total = buff->size(),
|
||||||
|
off = 0, size = total;
|
||||||
|
unsigned char* mem = buff->data(off, &size);
|
||||||
|
while (mem)
|
||||||
|
{
|
||||||
|
memcpy(buffer_->data(), mem, size);
|
||||||
|
off += size;
|
||||||
|
if (off >= total)
|
||||||
|
{
|
||||||
|
ret = SCANNER_ERR_OK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = total - off;
|
||||||
|
mem = buff->data(off, &size);
|
||||||
|
}
|
||||||
|
}
|
||||||
mats_.clear();
|
mats_.clear();
|
||||||
return SCANNER_ERR_OK;
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
int load_file(const char* path_file)
|
int load_file(const char* path_file)
|
||||||
{
|
{
|
||||||
|
|
|
@ -445,9 +445,27 @@ extern "C"
|
||||||
{
|
{
|
||||||
return g_scanner_path;
|
return g_scanner_path;
|
||||||
}
|
}
|
||||||
|
unsigned int get_page_size(void)
|
||||||
|
{
|
||||||
|
unsigned int ps = 1024;
|
||||||
|
#ifdef WIN32
|
||||||
|
SYSTEM_INFO si = { 0 };
|
||||||
|
|
||||||
|
GetSystemInfo(&si);
|
||||||
|
ps = si.dwPageSize;
|
||||||
|
#else
|
||||||
|
ps = sysconf(_SC_PAGESIZE);
|
||||||
|
if(ps < 1024 || (ps & 0x0fe0000ff)) // nKB && < 16MB
|
||||||
|
ps = getpagesize();
|
||||||
|
#endif
|
||||||
|
if (ps < 1024 || (ps & 0x0fe0000ff)) // nKB && < 16MB
|
||||||
|
ps = 1024;
|
||||||
|
|
||||||
|
return ps;
|
||||||
|
}
|
||||||
static int get_log_config(const std::string& self_path, hg_log_type* type, std::string* path)
|
static int get_log_config(const std::string& self_path, hg_log_type* type, std::string* path)
|
||||||
{
|
{
|
||||||
std::string me(self_path + PATH_SEPARATOR + "configs" + PATH_SEPARATOR + " scanner.conf");
|
std::string me(self_path + PATH_SEPARATOR + "Cfg" + PATH_SEPARATOR + " scanner.conf");
|
||||||
int lv = LOG_LEVEL_ALL;
|
int lv = LOG_LEVEL_ALL;
|
||||||
hg_log_type tp = LOG_TYPE_FILE;
|
hg_log_type tp = LOG_TYPE_FILE;
|
||||||
|
|
||||||
|
@ -477,31 +495,60 @@ extern "C"
|
||||||
else if (val == "fatal")
|
else if (val == "fatal")
|
||||||
lv = LOG_LEVEL_FATAL;
|
lv = LOG_LEVEL_FATAL;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
create_folder((self_path + PATH_SEPARATOR + "Cfg").c_str());
|
||||||
|
|
||||||
return lv;
|
return lv;
|
||||||
}
|
}
|
||||||
|
std::string local_data_path(void)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
char* tmp = getenv("TMP");
|
||||||
|
std::string home(tmp ? tmp : "");
|
||||||
|
|
||||||
|
if (home.length())
|
||||||
|
{
|
||||||
|
size_t pos = home.rfind('\\');
|
||||||
|
if (pos++ != std::string::npos)
|
||||||
|
home.erase(pos);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
std::string home(getenv("HOME"));
|
||||||
|
|
||||||
|
home += "/.";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OEM_HANWANG
|
||||||
|
home += "HwScanner";
|
||||||
|
#elif defined(OEM_LISICHENG)
|
||||||
|
home += "LscScanner";
|
||||||
|
#else
|
||||||
|
home += "HuaGoScan";
|
||||||
|
#endif;
|
||||||
|
create_folder(home.c_str());
|
||||||
|
|
||||||
|
return home;
|
||||||
|
}
|
||||||
|
|
||||||
int init(void)
|
int init(void)
|
||||||
{
|
{
|
||||||
char* file = nullptr;
|
char* file = nullptr;
|
||||||
std::string path("");
|
std::string path("");
|
||||||
hg_log_type type = LOG_TYPE_FILE;
|
hg_log_type type = LOG_TYPE_FILE;
|
||||||
int level = get_log_config(get_scanner_path(), &type, &path);
|
int level = get_log_config(local_data_path(), &type, &path);
|
||||||
|
|
||||||
if (type == LOG_TYPE_FILE)
|
if (type == LOG_TYPE_FILE)
|
||||||
{
|
{
|
||||||
std::string name(""),
|
std::string name(""),
|
||||||
paths[] = {pe_path(&name), get_scanner_path(), simple_ini::temporary_path()};
|
paths[] = { local_data_path(), pe_path(&name), get_scanner_path(), simple_ini::temporary_path()};
|
||||||
int ind = 0;
|
int ind = 0;
|
||||||
|
|
||||||
if (path.empty() || !create_folder(path.c_str()))
|
if (!path.empty() && create_folder(path.c_str()))
|
||||||
path = paths[ind++];
|
|
||||||
else
|
|
||||||
ind = sizeof(paths) / sizeof(paths[0]) + 2;
|
ind = sizeof(paths) / sizeof(paths[0]) + 2;
|
||||||
|
|
||||||
for (; ind < sizeof(paths) / sizeof(paths[0]); ++ind)
|
for (; ind < sizeof(paths) / sizeof(paths[0]); ++ind)
|
||||||
{
|
{
|
||||||
path = paths[ind] + PATH_SEPARATOR + "log";
|
path = paths[ind] + PATH_SEPARATOR + "Log";
|
||||||
if (create_folder(path.c_str()))
|
if (create_folder(path.c_str()))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,8 @@ extern "C"
|
||||||
std::string pe_path(std::string* name = nullptr);
|
std::string pe_path(std::string* name = nullptr);
|
||||||
std::string get_module_full_path(const char* module_part_name);
|
std::string get_module_full_path(const char* module_part_name);
|
||||||
std::string get_scanner_path(void);
|
std::string get_scanner_path(void);
|
||||||
|
std::string local_data_path(void);
|
||||||
|
unsigned int get_page_size(void);
|
||||||
unsigned long long available_memory(void);
|
unsigned long long available_memory(void);
|
||||||
void str_tolower(std::string& str);
|
void str_tolower(std::string& str);
|
||||||
bool create_folder(const char* fodler);
|
bool create_folder(const char* fodler);
|
||||||
|
|
Loading…
Reference in New Issue