Fixes #99 ("Error in win32_api.hpp"):

- Careful use of Boost.Winapi and use of SetFilePointer instead of SetFilePointerEx (which requires a _LARGE_INTEGER by value that difficults the use of windows.h in certain circustances)
- Added tests to verify windows.h inclusion without BOOST_USE_WINDOWS_H does not break things
This commit is contained in:
Ion Gaztañaga
2020-06-03 21:37:02 +02:00
parent ac63d25a4d
commit f2ecdc70ef
6 changed files with 154 additions and 26 deletions

View File

@@ -6763,6 +6763,20 @@ thank them:
[section:release_notes Release Notes]
[section:release_notes_boost_1_74_00 Boost 1.74 Release]
* [*ABI breaking]: Option `BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED` is now the default value.
You can obtain the pre-Boost 1.73 behaviour defining `BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED`.
The old and broken pre-Boost 1.54 behaviour (`BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME`) is no
longer available.
* Fixed bugs:
* [@https://github.com/boostorg/interprocess/issues/89 GitHub #89 (['"priv_size_from_mapping_size() calculates wrong value"])].
* [@https://github.com/boostorg/interprocess/issues/99 GitHub #99 (['"Error in win32_api.hpp"])].
* [@https://github.com/boostorg/interprocess/issues/89 GitHub #105 (['"Build failure with clang on Windows"])].
[endsect]
[section:release_notes_boost_1_71_00 Boost 1.71 Release]
* Fixed bugs:

View File

@@ -167,7 +167,7 @@ inline bool truncate_file (file_handle_t hnd, std::size_t size)
}
if(offset_t(size) > filesize){
if(!winapi::set_file_pointer_ex(hnd, filesize, 0, winapi::file_begin)){
if(!winapi::set_file_pointer(hnd, filesize, 0, winapi::file_begin)){
return false;
}
//We will write zeros in the end of the file
@@ -186,7 +186,7 @@ inline bool truncate_file (file_handle_t hnd, std::size_t size)
}
}
else{
if(!winapi::set_file_pointer_ex(hnd, size, 0, winapi::file_begin)){
if(!winapi::set_file_pointer(hnd, size, 0, winapi::file_begin)){
return false;
}
if(!winapi::set_end_of_file(hnd)){
@@ -200,10 +200,10 @@ inline bool get_file_size(file_handle_t hnd, offset_t &size)
{ return winapi::get_file_size(hnd, size); }
inline bool set_file_pointer(file_handle_t hnd, offset_t off, file_pos_t pos)
{ return winapi::set_file_pointer_ex(hnd, off, 0, (unsigned long) pos); }
{ return winapi::set_file_pointer(hnd, off, 0, (unsigned long) pos); }
inline bool get_file_pointer(file_handle_t hnd, offset_t &off)
{ return winapi::set_file_pointer_ex(hnd, 0, &off, winapi::file_current); }
{ return winapi::set_file_pointer(hnd, 0, &off, winapi::file_current); }
inline bool write_file(file_handle_t hnd, const void *data, std::size_t numdata)
{

View File

@@ -21,7 +21,7 @@
#include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/date_time/filetime_functions.hpp>
#include <boost/cstdint.hpp>
#include <cstddef>
#include <cstring>
#include <cstdlib>
@@ -279,6 +279,7 @@ enum section_information_class
#include <boost/winapi/get_current_thread_id.hpp>
#include <boost/winapi/get_current_process.hpp>
#include <boost/winapi/get_process_times.hpp>
#include <boost/winapi/error_codes.hpp>
#include <boost/winapi/thread.hpp>
#include <boost/winapi/system.hpp>
#include <boost/winapi/time.hpp>
@@ -303,11 +304,11 @@ namespace boost {
namespace ipwinapiext {
typedef boost::winapi::LONG_ LSTATUS;
#ifndef BOOST_USE_WINDOWS_H
typedef boost::winapi::LARGE_INTEGER_ LARGE_INTEGER_EXT;
#else
typedef LARGE_INTEGER LARGE_INTEGER_EXT;
#endif
//#ifndef BOOST_USE_WINDOWS_H
//typedef boost::winapi::LARGE_INTEGER_ LARGE_INTEGER_EXT;
//#else
//typedef LARGE_INTEGER LARGE_INTEGER_EXT;
//#endif
}} //namespace boost::ipwinapiext
@@ -320,8 +321,6 @@ BOOST_SYMBOL_IMPORT BOOST_WINAPI_DETAIL_VOID BOOST_WINAPI_WINAPI_CC SetLastError
//File management
BOOST_SYMBOL_IMPORT boost::winapi::DWORD_ BOOST_WINAPI_WINAPI_CC GetFileType(boost::winapi::HANDLE_ hTemplateFile);
BOOST_SYMBOL_IMPORT boost::winapi::BOOL_ BOOST_WINAPI_WINAPI_CC SetFilePointerEx( boost::winapi::HANDLE_ hFile, boost::ipwinapiext::LARGE_INTEGER_EXT liDistanceToMove
, ::_LARGE_INTEGER *lpNewFilePointer, boost::winapi::DWORD_ dwMoveMethod);
BOOST_SYMBOL_IMPORT boost::winapi::BOOL_ BOOST_WINAPI_WINAPI_CC FlushFileBuffers(boost::winapi::HANDLE_ hFile);
//Virtual Memory
BOOST_SYMBOL_IMPORT boost::winapi::BOOL_ BOOST_WINAPI_WINAPI_CC VirtualLock(boost::winapi::LPVOID_ lpAddress, boost::winapi::SIZE_T_ dwSize);
@@ -365,14 +364,6 @@ BOOST_FORCEINLINE BOOST_WINAPI_DETAIL_VOID SetLastError(boost::winapi::DWORD_ dw
BOOST_FORCEINLINE boost::winapi::DWORD_ GetFileType(boost::winapi::HANDLE_ hTemplateFile)
{ return ::GetFileType(hTemplateFile); }
BOOST_FORCEINLINE boost::winapi::BOOL_ SetFilePointerEx(boost::winapi::HANDLE_ hFile, boost::winapi::LARGE_INTEGER_ liDistanceToMove
, boost::winapi::PLARGE_INTEGER_ lpNewFilePointer, boost::winapi::DWORD_ dwMoveMethod)
{
boost::ipwinapiext::LARGE_INTEGER_EXT largeInt;
largeInt.QuadPart = liDistanceToMove.QuadPart;
return ::SetFilePointerEx(hFile, largeInt, reinterpret_cast< ::_LARGE_INTEGER* >(lpNewFilePointer), dwMoveMethod);
}
BOOST_FORCEINLINE boost::winapi::BOOL_ FlushFileBuffers(boost::winapi::HANDLE_ hFile)
{ return ::FlushFileBuffers(hFile); }
@@ -741,7 +732,7 @@ class interprocess_all_access_security
inline void * create_file_mapping (void * handle, unsigned long access, ::boost::ulong_long_type file_offset, const char * name, interprocess_security_attributes *psec)
{
const unsigned long high_size(file_offset >> 32), low_size((boost::uint32_t)file_offset);
const boost::winapi::DWORD_ high_size(file_offset >> 32), low_size((boost::winapi::DWORD_)file_offset);
return CreateFileMappingA (handle, psec, access, high_size, low_size, name);
}
@@ -806,10 +797,16 @@ inline unsigned long get_temp_path(unsigned long length, char *buffer)
inline int set_end_of_file(void *handle)
{ return 0 != boost::winapi::SetEndOfFile(handle); }
inline bool set_file_pointer_ex(void *handle, __int64 distance, __int64 *new_file_pointer, unsigned long move_method)
inline bool set_file_pointer(void *handle, __int64 distance, __int64 *new_file_pointer, unsigned long move_method)
{
boost::winapi::LARGE_INTEGER_ d; d.QuadPart = distance;
return 0 != boost::ipwinapiext::SetFilePointerEx(handle, d, (boost::winapi::LARGE_INTEGER_*)new_file_pointer, move_method);
long highPart = distance >> 32u;
boost::winapi::DWORD_ r = boost::winapi::SetFilePointer(handle, (unsigned long)distance, &highPart, move_method);
bool br = r != boost::winapi::INVALID_SET_FILE_POINTER_ || boost::winapi::GetLastError() != 0;
if (br && new_file_pointer){
*new_file_pointer = (unsigned __int64)r + ((__int64)highPart << 32);
}
return br;
}
inline bool lock_file_ex(void *hnd, unsigned long flags, unsigned long reserved, unsigned long size_low, unsigned long size_high, interprocess_overlapped *overlapped)
@@ -1150,7 +1147,7 @@ class nt_query_mem_deleter
offsetof(ntquery_mem_t, name.Name.Buffer);
// Timestamp process id atomic count
static const std::size_t rename_suffix =
(SystemTimeOfDayInfoLength + sizeof(unsigned long) + sizeof(boost::uint32_t))*2;
(SystemTimeOfDayInfoLength + sizeof(unsigned long) + sizeof(boost::winapi::DWORD_))*2;
public:
explicit nt_query_mem_deleter(std::size_t object_name_information_size)

View File

@@ -83,7 +83,7 @@ inline void windows_named_sync::close(windows_named_sync_interface &sync_interfa
winapi::interprocess_overlapped overlapped;
if(winapi::lock_file_ex
(m_file_hnd, winapi::lockfile_exclusive_lock, 0, sizeof_file_info, 0, &overlapped)){
if(winapi::set_file_pointer_ex(m_file_hnd, sizeof(sync_id::internal_type), 0, winapi::file_begin)){
if(winapi::set_file_pointer(m_file_hnd, sizeof(sync_id::internal_type), 0, winapi::file_begin)){
const void *buf = sync_interface.buffer_with_final_data_to_file();
unsigned long written_or_read = 0;

View File

@@ -0,0 +1,33 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/workaround.hpp>
#ifdef BOOST_INTERPROCESS_WINDOWS
#include <windows.h>
#include <boost/interprocess/windows_shared_memory.hpp>
using namespace boost::interprocess;
int main ()
{
windows_shared_memory dummy;
static_cast<void>(dummy);
return 0;
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -0,0 +1,84 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#define BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/detail/managed_open_or_create_impl.hpp>
#include <boost/interprocess/exceptions.hpp>
#include "named_creation_template.hpp"
#include <cstring> //for strcmp, memset
#include <iostream> //for cout
#include <string>
#include "get_process_id_name.hpp"
using namespace boost::interprocess;
static const std::size_t ShmSize = 1000;
static const char * ShmName = test::get_process_id_name();
struct eraser
{
~eraser()
{
shared_memory_object::remove(ShmName);
}
};
typedef ipcdetail::managed_open_or_create_impl<shared_memory_object, 0, true, false> shared_memory;
//This wrapper is necessary to have a common constructor
//in generic named_creation_template functions
class shared_memory_creation_test_wrapper
: public eraser
, public shared_memory
{
public:
shared_memory_creation_test_wrapper(create_only_t)
: shared_memory(create_only, ShmName, ShmSize, read_write, 0, permissions())
{}
shared_memory_creation_test_wrapper(open_only_t)
: shared_memory(open_only, ShmName, read_write, 0)
{}
shared_memory_creation_test_wrapper(open_or_create_t)
: shared_memory(open_or_create, ShmName, ShmSize, read_write, 0, permissions())
{}
};
int main ()
{
try{
shared_memory_object::remove(ShmName);
test::test_named_creation<shared_memory_creation_test_wrapper>();
//Create and get name, size and address
{
shared_memory_object::remove(ShmName);
shared_memory shm1(create_only, ShmName, ShmSize, read_write, 0, permissions());
//Overwrite all memory
std::memset(shm1.get_user_address(), 0, shm1.get_user_size());
//Now test move semantics
shared_memory move_ctor(boost::move(shm1));
shared_memory move_assign;
move_assign = boost::move(move_ctor);
}
}
catch(std::exception &ex){
shared_memory_object::remove(ShmName);
std::cout << ex.what() << std::endl;
return 1;
}
shared_memory_object::remove(ShmName);
return 0;
}