From 82b8b2cbf13b5cebd78d09d48bd4a4834016a468 Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Fri, 4 Jan 2013 13:20:12 +0100 Subject: [PATCH 01/12] Add Posix pthread mutex support. Former-commit-id: 1a6c8002e3fc70e557f0798a1cc78c3d430b853a --- src/Nazara/Core/Posix/MutexImpl.cpp | 32 ++++++++++++++++++++++++++++ src/Nazara/Core/Posix/MutexImpl.hpp | 33 +++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 src/Nazara/Core/Posix/MutexImpl.cpp create mode 100644 src/Nazara/Core/Posix/MutexImpl.hpp diff --git a/src/Nazara/Core/Posix/MutexImpl.cpp b/src/Nazara/Core/Posix/MutexImpl.cpp new file mode 100644 index 000000000..1916eeb57 --- /dev/null +++ b/src/Nazara/Core/Posix/MutexImpl.cpp @@ -0,0 +1,32 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +NzMutexImpl::NzMutexImpl() +{ + + pthread_mutex_init(&m_pmutex, NULL); +} + +NzMutexImpl::~NzMutexImpl() +{ + pthread_mutex_ +} + +void NzMutexImpl::Lock() +{ + pthread_mutex_lock(&m_pmutex); +} + +bool NzMutexImpl::TryLock() +{ + pthread_mutex_trylock(&m_pmutex) == 0; +} + +void NzMutexImpl::Unlock() +{ + pthread_mutex_unlock(&m_pmutex); +} diff --git a/src/Nazara/Core/Posix/MutexImpl.hpp b/src/Nazara/Core/Posix/MutexImpl.hpp new file mode 100644 index 000000000..a3cdad284 --- /dev/null +++ b/src/Nazara/Core/Posix/MutexImpl.hpp @@ -0,0 +1,33 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +/* + 04/01/2012 : alexandre.janniaux@gmail.com + Add pthread mutex implementation +*/ + +#pragma once + +#ifndef NAZARA_MUTEXIMPL_HPP +#define NAZARA_MUTEXIMPL_HPP + +#include + +class NzMutexImpl +{ + friend class NzConditionVariableImpl; + + public: + NzMutexImpl(); + ~NzMutexImpl(); + + void Lock(); + bool TryLock(); + void Unlock(); + + private: + pthread_mutex_t m_pmutex; +}; + +#endif // NAZARA_MUTEXIMPL_HPP From 9415096975b7328d9de891a992e2a18c1c45275a Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Fri, 4 Jan 2013 15:52:15 +0100 Subject: [PATCH 02/12] Add Posix file support. Former-commit-id: 7bff867c4e43f3755455217887e77c7634d82ca5 --- src/Nazara/Core/Posix/FileImpl.cpp | 249 +++++++++++++++++++++++++++++ src/Nazara/Core/Posix/FileImpl.hpp | 55 +++++++ 2 files changed, 304 insertions(+) create mode 100644 src/Nazara/Core/Posix/FileImpl.cpp create mode 100644 src/Nazara/Core/Posix/FileImpl.hpp diff --git a/src/Nazara/Core/Posix/FileImpl.cpp b/src/Nazara/Core/Posix/FileImpl.cpp new file mode 100644 index 000000000..09584ceea --- /dev/null +++ b/src/Nazara/Core/Posix/FileImpl.cpp @@ -0,0 +1,249 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include +#include + +NzFileImpl::NzFileImpl(const NzFile* parent) : +m_endOfFile(false), +m_endOfFileUpdated(true) +{ + NazaraUnused(parent); +} + +void NzFileImpl::Close() +{ + close(m_fileDescriptor); +} + +bool NzFileImpl::EndOfFile() const +{ + if (!m_endOfFileUpdated) + { + stat64 fileSize; + if (fstat64(m_handle, &fileSize) == -1) + fileSize.st_size = 0; + + m_endOfFile = (GetCursorPos() >= static_cast(fileSize.st_size)); + m_endOfFileUpdated = true; + } + + return m_endOfFile; +} + +void NzFileImpl::Flush() +{ + if (fsync(m_fileDescriptor) == -1) + NazaraError("Unable to flush file: " + NzGetLastSystemError()); +} + +nzUInt64 NzFileImpl::GetCursorPos() const +{ + off64_t position = lseek64(m_fileDescriptor, 0, SEEK_CUR); + return static_cast(position); +} + +bool NzFileImpl::Open(const NzString& filePath, unsigned int mode) +{ + int flags; + mode_t permissions = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; + + if (mode & NzFile::ReadOnly) + flags = O_RDONLY; + + else if (mode & NzFile::ReadWrite) + { + flags = O_CREAT | O_RDWR; + + if (mode & NzFile::Append) + flags |= O_APPEND; + + if (mode & NzFile::Truncate) + flags |= O_TRUNC; + + } + else if (mode & NzFile::WriteOnly) + { + flags = O_CREAT | O_WRONLY; + + if (mode & NzFile::Append) + flags |= O_APPEND; + + if (mode & NzFile::Truncate) + flags |= O_TRUNC; + } + else + return false; + +// TODO: lock +// if ((mode & NzFile::Lock) == 0) +// shareMode |= FILE_SHARE_WRITE; + + const char* path = filePath.GetConstBuffer(); + + m_fileDescriptor = open64(path, flags, permissions); + return m_fileDescriptor != -1; +} + +std::size_t NzFileImpl::Read(void* buffer, std::size_t size) +{ + ssize_t bytes; + if ((bytes = read(m_fileDescriptor, buffer, size)) != -1) + { + m_endOfFile = (static_cast(bytes) != size); + m_endOfFileUpdated = true; + + return static_cast(bytes); + } + else + return 0; +} + +bool NzFileImpl::SetCursorPos(NzFile::CursorPosition pos, nzInt64 offset) +{ + int moveMethod; + switch (pos) + { + case NzFile::AtBegin: + moveMethod = SEEK_SET; + break; + + case NzFile::AtCurrent: + moveMethod = SEEK_CUR; + break; + + case NzFile::AtEnd: + moveMethod = SEEK_END; + break; + + default: + NazaraInternalError("Cursor position not handled (0x" + NzString::Number(pos, 16) + ')'); + return false; + } + + m_endOfFileUpdated = false; + + return lseek64(m_fileDescriptor, offset, moveMethod) != -1; +} + +std::size_t NzFileImpl::Write(const void* buffer, std::size_t size) +{ + lockf64(m_fileDescriptor, F_LOCK, size); + ssize_t written = write(m_fileDescriptor, buffer, size); + lockf64(m_fileDescriptor, F_ULOCK, size); + + m_endOfFileUpdated = false; + + return written; +} + +bool NzFileImpl::Copy(const NzString& sourcePath, const NzString& targetPath) +{ + int fd1 = open64(sourcePath.GetConstBuffer(), O_RDONLY); + if (fd1 == -1) + { + NazaraError("Fail to open input file (" + sourcePath + "): " + NzGetLastSystemError()); + return false; + } + + mode_t permissions; // TODO : get permission from first file + int fd2 = open64(sourcePath.GetConstBuffer(), O_WRONLY | O_TRUNC, permissions); + if (fd2 == -1) + { + NazaraError("Fail to open output file (" + targetPath + "): " + NzGetLastSystemError()); // TODO: more info ? + return false; + } + + + char buffer[512]; + ssize_t bytes; + do + { + bytes = read(fd1,buffer,512); + if (bytes == -1) + { + close(fd1); + close(fd2); + NazaraError("An error occured from copy : " + NzGetLastSystemError()); + return false; + } + write(fd2,buffer,bytes); + + } while (bytes == 512); +} + +bool NzFileImpl::Delete(const NzString& filePath) +{ + const char* path = filePath.GetConstBuffer(); + bool success = unlink(path) != -1; + + if (success) + return true; + else + { + NazaraError("Failed to delete file (" + filePath + "): " + NzGetLastSystemError()); + return false; + } +} + +bool NzFileImpl::Exists(const NzString& filePath) +{ + char* path = filePath.GetConstBuffer(); + if (access(path, F_OK) != -1) + return true; + return false; +} + +time_t NzFileImpl::GetCreationTime(const NzString& filePath) +{ + struct stat64 stats; + stat64(filePath.GetConstBuffer(), &stats); + + return NzFileTimeToTime(std::ctime(&stats.st_ctim)); // not sure ? +} + +time_t NzFileImpl::GetLastAccessTime(const NzString& filePath) +{ + struct stat64 stats; + stat64(filePath.GetConstBuffer(), &stats); + + return NzFileTimeToTime(std::ctime(&stats.st_atim)); +} + +time_t NzFileImpl::GetLastWriteTime(const NzString& filePath) +{ + struct stat64 stats; + stat64(filePath.GetConstBuffer(), &stats); + + return NzFileTimeToTime(std::ctime(&stats.st_mtim)); +} + +nzUInt64 NzFileImpl::GetSize(const NzString& filePath) +{ + struct stat64 stats; + stat64(filePath.GetConstBuffer(), &stats); + + return static_cast(stats.st_size); +} + +bool NzFileImpl::Rename(const NzString& sourcePath, const NzString& targetPath) +{ + const char* path = sourcePath.GetConstBuffer(); + const char* newPath = targetPath.GetConstBuffer(); + + bool success = std::rename(path, newPath) != -1; + + if (success) + return true; + else + { + NazaraError("Unable to rename file: " + NzGetLastSystemError()); + return false; + } +} diff --git a/src/Nazara/Core/Posix/FileImpl.hpp b/src/Nazara/Core/Posix/FileImpl.hpp new file mode 100644 index 000000000..d6ed7d378 --- /dev/null +++ b/src/Nazara/Core/Posix/FileImpl.hpp @@ -0,0 +1,55 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_FILEIMPL_HPP +#define NAZARA_FILEIMPL_HPP + +#define _LARGEFILE64_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include + +class NzFile; +class NzString; + +class NzFileImpl : NzNonCopyable +{ + public: + NzFileImpl(const NzFile* parent); + ~NzFileImpl() = default; + + void Close(); + bool EndOfFile() const; + void Flush(); + nzUInt64 GetCursorPos() const; + bool Open(const NzString& filePath, unsigned int mode); + std::size_t Read(void* buffer, std::size_t size); + bool SetCursorPos(NzFile::CursorPosition pos, nzInt64 offset); + std::size_t Write(const void* buffer, std::size_t size); + + static bool Copy(const NzString& sourcePath, const NzString& targetPath); + static bool Delete(const NzString& filePath); + static bool Exists(const NzString& filePath); + static time_t GetCreationTime(const NzString& filePath); + static time_t GetLastAccessTime(const NzString& filePath); + static time_t GetLastWriteTime(const NzString& filePath); + static nzUInt64 GetSize(const NzString& filePath); + static bool Rename(const NzString& sourcePath, const NzString& targetPath); + + private: + int m_fileDescriptor; + FILE* m_handle; + mutable bool m_endOfFile; + mutable bool m_endOfFileUpdated; +}; + +#endif // NAZARA_FILEIMPL_HPP From ce6a63647fa38e965902914f59ff999af8ef92bb Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Fri, 4 Jan 2013 15:54:39 +0100 Subject: [PATCH 03/12] Forgot to close files after copy or error. Former-commit-id: 157ea611926a5d70d1b469714b6b27b78d513f4b --- src/Nazara/Core/Posix/FileImpl.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Nazara/Core/Posix/FileImpl.cpp b/src/Nazara/Core/Posix/FileImpl.cpp index 09584ceea..38935fe12 100644 --- a/src/Nazara/Core/Posix/FileImpl.cpp +++ b/src/Nazara/Core/Posix/FileImpl.cpp @@ -157,6 +157,7 @@ bool NzFileImpl::Copy(const NzString& sourcePath, const NzString& targetPath) if (fd2 == -1) { NazaraError("Fail to open output file (" + targetPath + "): " + NzGetLastSystemError()); // TODO: more info ? + close(fd1); return false; } @@ -176,6 +177,9 @@ bool NzFileImpl::Copy(const NzString& sourcePath, const NzString& targetPath) write(fd2,buffer,bytes); } while (bytes == 512); + + close(fd1); + close(fd2); } bool NzFileImpl::Delete(const NzString& filePath) From 22d9e98422f9496e8de09022e36b274c41ff02f2 Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Fri, 4 Jan 2013 16:02:21 +0100 Subject: [PATCH 04/12] Add posix DynLibImpl support. Former-commit-id: c80dcc31c0935916082d5f19a7cf2dbe15da7b2f --- src/Nazara/Core/Posix/DynLibImpl.cpp | 45 ++++++++++++++++++++++++++++ src/Nazara/Core/Posix/DynLibImpl.hpp | 31 +++++++++++++++++++ src/Nazara/Core/Posix/FileImpl.hpp | 5 ++++ src/Nazara/Core/Posix/MutexImpl.hpp | 2 +- 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 src/Nazara/Core/Posix/DynLibImpl.cpp create mode 100644 src/Nazara/Core/Posix/DynLibImpl.hpp diff --git a/src/Nazara/Core/Posix/DynLibImpl.cpp b/src/Nazara/Core/Posix/DynLibImpl.cpp new file mode 100644 index 000000000..6dc2182c8 --- /dev/null +++ b/src/Nazara/Core/Posix/DynLibImpl.cpp @@ -0,0 +1,45 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include + +NzDynLibImpl::NzDynLibImpl(NzDynLib* parent) : +m_parent(parent) +{ +} + +NzDynLibFunc NzDynLibImpl::GetSymbol(const NzString& symbol) const +{ + NzDynLibFunc sym = reinterpret_cast(dlsym(m_handle, symbol.GetConstBuffer())); + if (!sym) + m_parent->SetLastError(NzGetLastSystemError()); // dlerror() ? + + return sym; +} + +bool NzDynLibImpl::Load(const NzString& libraryPath) +{ + NzString path = libraryPath; + if (!path.EndsWith(".so")) + path += ".so"; + + m_handle = dlopen(path.GetConstBuffer(),); + + if (m_handle) + return true; + else + { + m_parent->SetLastError(NzGetLastSystemError()); + return false; + } +} + +void NzDynLibImpl::Unload() +{ + dlclose(m_handle); +} diff --git a/src/Nazara/Core/Posix/DynLibImpl.hpp b/src/Nazara/Core/Posix/DynLibImpl.hpp new file mode 100644 index 000000000..8b2831ccf --- /dev/null +++ b/src/Nazara/Core/Posix/DynLibImpl.hpp @@ -0,0 +1,31 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_DYNLIBIMPL_HPP +#define NAZARA_DYNLIBIMPL_HPP + +#include +#include +#include + +class NzString; + +class NzDynLibImpl : NzNonCopyable +{ + public: + NzDynLibImpl(NzDynLib* m_parent); + ~NzDynLibImpl() = default; + + NzDynLibFunc GetSymbol(const NzString& symbol) const; + bool Load(const NzString& libraryPath); + void Unload(); + + private: + void* m_handle; + NzDynLib* m_parent; +}; + +#endif // NAZARA_DYNLIBIMPL_HPP diff --git a/src/Nazara/Core/Posix/FileImpl.hpp b/src/Nazara/Core/Posix/FileImpl.hpp index d6ed7d378..7d2171cef 100644 --- a/src/Nazara/Core/Posix/FileImpl.hpp +++ b/src/Nazara/Core/Posix/FileImpl.hpp @@ -18,6 +18,11 @@ #include #include +/* + 04/01/2012 : alexandre.janniaux@gmail.com + Add posix file implementation. +*/ + class NzFile; class NzString; diff --git a/src/Nazara/Core/Posix/MutexImpl.hpp b/src/Nazara/Core/Posix/MutexImpl.hpp index a3cdad284..33c4c65e4 100644 --- a/src/Nazara/Core/Posix/MutexImpl.hpp +++ b/src/Nazara/Core/Posix/MutexImpl.hpp @@ -4,7 +4,7 @@ /* 04/01/2012 : alexandre.janniaux@gmail.com - Add pthread mutex implementation + Add pthread mutex implementation. */ #pragma once From cb5c8d7bdcfc4e325cc13cd812ec1f7ed69703e1 Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Fri, 4 Jan 2013 18:19:13 +0100 Subject: [PATCH 05/12] Fixes. Former-commit-id: 85f7bb85e33acdd84d19191c845a1cc59bbb2138 --- src/Nazara/Core/Posix/DynLibImpl.cpp | 2 +- src/Nazara/Core/Posix/FileImpl.cpp | 2 +- src/Nazara/Core/Posix/FileImpl.hpp | 2 ++ src/Nazara/Core/Posix/MutexImpl.cpp | 12 ++++++------ src/Nazara/Core/Posix/MutexImpl.hpp | 2 +- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Nazara/Core/Posix/DynLibImpl.cpp b/src/Nazara/Core/Posix/DynLibImpl.cpp index 6dc2182c8..acc54f455 100644 --- a/src/Nazara/Core/Posix/DynLibImpl.cpp +++ b/src/Nazara/Core/Posix/DynLibImpl.cpp @@ -2,7 +2,7 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include #include #include diff --git a/src/Nazara/Core/Posix/FileImpl.cpp b/src/Nazara/Core/Posix/FileImpl.cpp index 38935fe12..1db95f04e 100644 --- a/src/Nazara/Core/Posix/FileImpl.cpp +++ b/src/Nazara/Core/Posix/FileImpl.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/Nazara/Core/Posix/FileImpl.hpp b/src/Nazara/Core/Posix/FileImpl.hpp index 7d2171cef..c7abdc1dc 100644 --- a/src/Nazara/Core/Posix/FileImpl.hpp +++ b/src/Nazara/Core/Posix/FileImpl.hpp @@ -7,7 +7,9 @@ #ifndef NAZARA_FILEIMPL_HPP #define NAZARA_FILEIMPL_HPP +#ifndef _LARGEFILE64_SOURCE #define _LARGEFILE64_SOURCE +#endif #include #include diff --git a/src/Nazara/Core/Posix/MutexImpl.cpp b/src/Nazara/Core/Posix/MutexImpl.cpp index 1916eeb57..81615e71a 100644 --- a/src/Nazara/Core/Posix/MutexImpl.cpp +++ b/src/Nazara/Core/Posix/MutexImpl.cpp @@ -2,31 +2,31 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include NzMutexImpl::NzMutexImpl() { - pthread_mutex_init(&m_pmutex, NULL); + pthread_mutex_init(&m_handle, NULL); } NzMutexImpl::~NzMutexImpl() { - pthread_mutex_ + pthread_mutex_destroy(&m_handle); } void NzMutexImpl::Lock() { - pthread_mutex_lock(&m_pmutex); + pthread_mutex_lock(&m_handle); } bool NzMutexImpl::TryLock() { - pthread_mutex_trylock(&m_pmutex) == 0; + pthread_mutex_trylock(&m_handle) == 0; } void NzMutexImpl::Unlock() { - pthread_mutex_unlock(&m_pmutex); + pthread_mutex_unlock(&m_handle); } diff --git a/src/Nazara/Core/Posix/MutexImpl.hpp b/src/Nazara/Core/Posix/MutexImpl.hpp index 33c4c65e4..0cb77e608 100644 --- a/src/Nazara/Core/Posix/MutexImpl.hpp +++ b/src/Nazara/Core/Posix/MutexImpl.hpp @@ -27,7 +27,7 @@ class NzMutexImpl void Unlock(); private: - pthread_mutex_t m_pmutex; + pthread_mutex_t m_handle; }; #endif // NAZARA_MUTEXIMPL_HPP From 36774013196d20bb192e70ad94c85ee4e424d380 Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Fri, 4 Jan 2013 18:19:44 +0100 Subject: [PATCH 06/12] Add posix thread support. Former-commit-id: fcab7f0b38965e4435abe683d9edc7de27df2621 --- src/Nazara/Core/Posix/ThreadImpl.cpp | 80 ++++++++++++++++++++++++++++ src/Nazara/Core/Posix/ThreadImpl.hpp | 35 ++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 src/Nazara/Core/Posix/ThreadImpl.cpp create mode 100644 src/Nazara/Core/Posix/ThreadImpl.hpp diff --git a/src/Nazara/Core/Posix/ThreadImpl.cpp b/src/Nazara/Core/Posix/ThreadImpl.cpp new file mode 100644 index 000000000..d63fac4c8 --- /dev/null +++ b/src/Nazara/Core/Posix/ThreadImpl.cpp @@ -0,0 +1,80 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include + +NzThreadImpl::NzThreadImpl(NzFunctor* functor) +{ + int error = pthread_create(&m_handle, nullptr, &NzThreadImpl::ThreadProc, functor); + + if (error != 0) + NazaraInternalError("Failed to create thread: " + NzGetLastSystemError()); +} + +void NzThreadImpl::Detach() +{ + // http://stackoverflow.com/questions/418742/is-it-reasonable-to-call-closehandle-on-a-thread-before-it-terminates + pthread_detach(&m_handle); +} + +void NzThreadImpl::Join() +{ + pthread_join(&m_handle, nullptr); +} + +unsigned int __stdcall NzThreadImpl::ThreadProc(void* userdata) +{ + NzFunctor* func = static_cast(userdata); + func->Run(); + delete func; + + /* + En C++, il vaut mieux retourner depuis la fonction que de quitter le thread explicitement + Source : http://msdn.microsoft.com/en-us/library/windows/desktop/ms682659(v=vs.85).aspx + */ + + return 0; +} + +void NzThreadImpl::Sleep(nzUInt32 time) +{ + // code from SFML2 Unix SleepImpl.cpp source https://github.com/LaurentGomila/SFML/blob/master/src/SFML/System/Unix/SleepImpl.cpp + + // usleep is not reliable enough (it might block the + // whole process instead of just the current thread) + // so we must use pthread_cond_timedwait instead + + // this implementation is inspired from Qt + + nzUint64 usecs = time.asMicroseconds(); + + // get the current time + timeval tv; + gettimeofday(&tv, NULL); + + // construct the time limit (current time + time to wait) + timespec ti; + ti.tv_nsec = (tv.tv_usec + (usecs % 1000000)) * 1000; + ti.tv_sec = tv.tv_sec + (usecs / 1000000) + (ti.tv_nsec / 1000000000); + ti.tv_nsec %= 1000000000; + + // create a mutex and thread condition + pthread_mutex_t mutex; + pthread_mutex_init(&mutex, 0); + pthread_cond_t condition; + pthread_cond_init(&condition, 0); + + // wait... + pthread_mutex_lock(&mutex); + pthread_cond_timedwait(&condition, &mutex, &ti); + pthread_mutex_unlock(&mutex); + + // destroy the mutex and condition + pthread_cond_destroy(&condition); + pthread_mutex_destroy(&mutex); +} diff --git a/src/Nazara/Core/Posix/ThreadImpl.hpp b/src/Nazara/Core/Posix/ThreadImpl.hpp new file mode 100644 index 000000000..f3213ae24 --- /dev/null +++ b/src/Nazara/Core/Posix/ThreadImpl.hpp @@ -0,0 +1,35 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +// Inspiré du code de la SFML par Laurent Gomila + +#pragma once + +#ifndef NAZARA_THREADIMPL_HPP +#define NAZARA_THREADIMPL_HPP + +#include +#include +#include +#include + +struct NzFunctor; + +class NzThreadImpl +{ + public: + NzThreadImpl(NzFunctor* threadFunc); + + void Detach(); + void Join(); + + static void Sleep(nzUInt32 time); + + private: + static unsigned int ThreadProc(void* userdata); + + pthread_t m_handle; +}; + +#endif // NAZARA_THREADIMPL_HPP From 50870b9a2d9b338a5211e962f56be21be6dec4d0 Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Fri, 4 Jan 2013 18:20:42 +0100 Subject: [PATCH 07/12] Add Posix condition variable support. Former-commit-id: 2af214aa206f2f9486c96750ccd412ac672ef62d --- .../Core/Posix/ConditionVariableImpl.cpp | 52 +++++++++++++++++++ .../Core/Posix/ConditionVariableImpl.hpp | 37 +++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 src/Nazara/Core/Posix/ConditionVariableImpl.cpp create mode 100644 src/Nazara/Core/Posix/ConditionVariableImpl.hpp diff --git a/src/Nazara/Core/Posix/ConditionVariableImpl.cpp b/src/Nazara/Core/Posix/ConditionVariableImpl.cpp new file mode 100644 index 000000000..563ff8a1b --- /dev/null +++ b/src/Nazara/Core/Posix/ConditionVariableImpl.cpp @@ -0,0 +1,52 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +// Source: http://www.cs.wustl.edu/~schmidt/win32-cv-1.html + +#include +#include +#include + +NzConditionVariableImpl::NzConditionVariableImpl() +{ + pthread_cond_init(&m_cv, nullptr); +} + +NzConditionVariableImpl::~NzConditionVariableImpl() +{ + pthread_cond_destroy(&m_cv); +} + +void NzConditionVariableImpl::Signal() +{ + pthread_cond_signal(&m_cv); +} + +void NzConditionVariableImpl::SignalAll() +{ + pthread_cond_broadcast(&m_cv); +} + +void NzConditionVariableImpl::Wait(NzMutexImpl* mutex) +{ + pthread_cond_wait(&m_cv, mutex); +} + +bool NzConditionVariableImpl::Wait(NzMutexImpl* mutex, nzUInt32 timeout) +{ + + + // get the current time + timeval tv; + gettimeofday(&tv, NULL); + + // construct the time limit (current time + time to wait) + timespec ti; + ti.tv_nsec = (tv.tv_usec + (timeout % 1000)) * 1000000; + ti.tv_sec = tv.tv_sec + (timeout / 1000) + (ti.tv_nsec / 1000000000); + ti.tv_nsec %= 1000000000; + + pthread_cond_timedwait(&m_cv,mutex, &tv); + +} diff --git a/src/Nazara/Core/Posix/ConditionVariableImpl.hpp b/src/Nazara/Core/Posix/ConditionVariableImpl.hpp new file mode 100644 index 000000000..25eb2bc92 --- /dev/null +++ b/src/Nazara/Core/Posix/ConditionVariableImpl.hpp @@ -0,0 +1,37 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html + +#pragma once + +#ifndef NAZARA_CONDITIONVARIABLEIMPL_HPP +#define NAZARA_CONDITIONVARIABLEIMPL_HPP + +#include +#include +#include +#include + +class NzMutexImpl; + +class NzConditionVariableImpl +{ + public: + NzConditionVariableImpl(); + ~NzConditionVariableImpl(); + + + void Signal(); + void SignalAll(); + + void Wait(NzMutexImpl* mutex); + bool Wait(NzMutexImpl* mutex, nzUInt32 timeout); + + private: + + pthread_cond_t m_cv; +}; + +#endif // NAZARA_CONDITIONVARIABLEIMPL_HPP From 1d224d23f6b47afe0fc1d7eac0e0d59600f7df75 Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Fri, 4 Jan 2013 18:21:19 +0100 Subject: [PATCH 08/12] Add Posix clock support. Former-commit-id: 1631e1028e94a88f7d19d7c217d83b8ae17936d7 --- src/Nazara/Core/Posix/ClockImpl.cpp | 30 +++++++++++++++++++++++++++++ src/Nazara/Core/Posix/ClockImpl.hpp | 16 +++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/Nazara/Core/Posix/ClockImpl.cpp create mode 100644 src/Nazara/Core/Posix/ClockImpl.hpp diff --git a/src/Nazara/Core/Posix/ClockImpl.cpp b/src/Nazara/Core/Posix/ClockImpl.cpp new file mode 100644 index 000000000..f6dde0d95 --- /dev/null +++ b/src/Nazara/Core/Posix/ClockImpl.cpp @@ -0,0 +1,30 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include + + +bool NzClockImplInitializeHighPrecision() +{ + // No initialization needed +} + +nzUInt64 NzClockImplGetMicroseconds() +{ + timeval clock; + gettimeofday(&clock, nullptr); + return static_cast(clock.tv_sec*1000000 + (clock.tv_nsec/1000)); + +} + +nzUInt64 NzClockImplGetMilliseconds() +{ + timeval clock; + gettimeofday(&clock, nullptr); + return static_cast(clock.tv_sec*1000 + (clock.tv_nsec/1000000)); +} diff --git a/src/Nazara/Core/Posix/ClockImpl.hpp b/src/Nazara/Core/Posix/ClockImpl.hpp new file mode 100644 index 000000000..896e7f076 --- /dev/null +++ b/src/Nazara/Core/Posix/ClockImpl.hpp @@ -0,0 +1,16 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_CLOCKIMPL_POSIX_HPP +#define NAZARA_CLOCKIMPL_POSIX_HPP + +#include + +bool NzClockImplInitializeHighPrecision(); +nzUInt64 NzClockImplGetMicroseconds(); +nzUInt64 NzClockImplGetMilliseconds(); + +#endif // NAZARA_CLOCKIMPL_POSIX_HPP From 1b9a86d993fea5b1d99a95a83be771ac0b97aaae Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Fri, 4 Jan 2013 18:21:45 +0100 Subject: [PATCH 09/12] Add Posix semaphore support. Former-commit-id: 1148708ccb60bf385a8b21da4c5ed1b9a0108441 --- src/Nazara/Core/Posix/SemaphoreImpl.cpp | 68 +++++++++++++++++++++++++ src/Nazara/Core/Posix/SemaphoreImpl.hpp | 28 ++++++++++ 2 files changed, 96 insertions(+) create mode 100644 src/Nazara/Core/Posix/SemaphoreImpl.cpp create mode 100644 src/Nazara/Core/Posix/SemaphoreImpl.hpp diff --git a/src/Nazara/Core/Posix/SemaphoreImpl.cpp b/src/Nazara/Core/Posix/SemaphoreImpl.cpp new file mode 100644 index 000000000..a88a68ca7 --- /dev/null +++ b/src/Nazara/Core/Posix/SemaphoreImpl.cpp @@ -0,0 +1,68 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include + +NzSemaphoreImpl::NzSemaphoreImpl(unsigned int count) +{ + m_semaphore = sem_init(&m_semaphore, 0, count); + if (!m_semaphore) + NazaraError("Failed to create semaphore: " + NzGetLastSystemError()); +} + +NzSemaphoreImpl::~NzSemaphoreImpl() +{ + sem_destroy(&m_semaphore); +} + +unsigned int NzSemaphoreImpl::GetCount() const +{ + int count; + sem_getvalue(&m_semaphore, &count); + return static_cast(count); +} + +void NzSemaphoreImpl::Post() +{ + #if NAZARA_CORE_SAFE + if (sem_post(&m_semaphore)==-1) + NazaraError("Failed to release semaphore: " + NzGetLastSystemError()); + #else + sem_post(&m_semaphore); + #endif +} + +void NzSemaphoreImpl::Wait() +{ + #if NAZARA_CORE_SAFE + if (sem_wait(&m_semaphore) == -1 ) + NazaraError("Failed to wait for semaphore: " + NzGetLastSystemError()); + #else + sem_wait(&m_semaphore); + #endif +} + +bool NzSemaphoreImpl::Wait(nzUInt32 timeout) +{ + timespec ti; + ti.tv_nsec = (tv.tv_usec + (timeout % 1000)) * 1000000; + ti.tv_sec = tv.tv_sec + (timeout / 1000) + (ti.tv_nsec / 1000000000); + ti.tv_nsec %= 1000000000; + + #if NAZARA_CORE_SAFE + if (sem_timedwait(m_semaphore, timeout) == -1) + { + NazaraError("Failed to wait for semaphore: " + NzGetLastSystemError()); + return false; + } + + return true; + #else + return sem_timedwait(&m_semaphore, ti) != -1; + #endif +} diff --git a/src/Nazara/Core/Posix/SemaphoreImpl.hpp b/src/Nazara/Core/Posix/SemaphoreImpl.hpp new file mode 100644 index 000000000..beae9028a --- /dev/null +++ b/src/Nazara/Core/Posix/SemaphoreImpl.hpp @@ -0,0 +1,28 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_SEMAPHOREIMPL_HPP +#define NAZARA_SEMAPHOREIMPL_HPP + +#include +#include + +class NzSemaphoreImpl +{ + public: + NzSemaphoreImpl(unsigned int count); + ~NzSemaphoreImpl(); + + unsigned int GetCount() const; + void Post(); + void Wait(); + bool Wait(nzUInt32 timeout); + + private: + sem_t m_semaphore; +}; + +#endif // NAZARA_SEMAPHOREIMPL_HPP From cf85e22c30cdef72cfa97142bb919624117a4fea Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Fri, 4 Jan 2013 18:22:13 +0100 Subject: [PATCH 10/12] Add Posix directory support. Former-commit-id: 308d7ce06c694cb869064ab2d2a5628475febf88 --- src/Nazara/Core/Posix/DirectoryImpl.cpp | 101 ++++++++++++++++++++++++ src/Nazara/Core/Posix/DirectoryImpl.hpp | 48 +++++++++++ 2 files changed, 149 insertions(+) create mode 100644 src/Nazara/Core/Posix/DirectoryImpl.cpp create mode 100644 src/Nazara/Core/Posix/DirectoryImpl.hpp diff --git a/src/Nazara/Core/Posix/DirectoryImpl.cpp b/src/Nazara/Core/Posix/DirectoryImpl.cpp new file mode 100644 index 000000000..c0cce52e7 --- /dev/null +++ b/src/Nazara/Core/Posix/DirectoryImpl.cpp @@ -0,0 +1,101 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + + +NzDirectoryImpl::NzDirectoryImpl(const NzDirectory* parent) +{ + NazaraUnused(parent); +} + +void NzDirectoryImpl::Close() +{ + closedir(m_handle); +} + +NzString NzDirectoryImpl::GetResultName() const +{ + return NzString::Unicode(m_result.d_name); +} + +nzUInt64 NzDirectoryImpl::GetResultSize() const +{ + struct stat64 resulststat; + stat64(m_result.d_name, &resulststat); + + return static_cast(resulststat.st_size); +} + +bool NzDirectoryImpl::IsResultDirectory() const +{ + return S_ISDIR(m_result.d_name); +} + +bool NzDirectoryImpl::NextResult() +{ + + if (m_result = readdir64(m_handle)) + return true; + else + { + if (errno != ENOENT) + NazaraError("Unable to get next result: " + NzGetLastSystemError()); + + return false; + } +} + +bool NzDirectoryImpl::Open(const NzString& dirPath) +{ + m_handle = opendir(dirPath.GetConstBuffer()); + + if (m_handle == NULL) + { + NazaraError("Unable to open directory: " + NzGetLastSystemError()); + return false; + } + + return true; +} + +bool NzDirectoryImpl::Create(const NzString& dirPath) +{ + mode_t permissions; // TODO: check permissions + bool success = mkdir(dirPath.GetConstBuffer(), permissions) != -1; + + return success; +} + +bool NzDirectoryImpl::Exists(const NzString& dirPath) +{ + if (S_ISDIR(dirPath.GetConstBuffer())) + return true; + return false; +} + +NzString NzDirectoryImpl::GetCurrent() +{ + NzString currentPath; + char* path = new char[_PC_PATH_MAX]; + + if (getcwd(path, _PC_PATH_MAX)) + currentPath = NzString::Unicode(path); + else + NazaraError("Unable to get current directory: " + NzGetLastSystemError()); + + delete[] path; + + return currentPath; +} + +bool NzDirectoryImpl::Remove(const NzString& dirPath) +{ + + bool success = rmdir(dirPath.GetConstBuffer()) != -1; + + return success; +} diff --git a/src/Nazara/Core/Posix/DirectoryImpl.hpp b/src/Nazara/Core/Posix/DirectoryImpl.hpp new file mode 100644 index 000000000..ffffc68d7 --- /dev/null +++ b/src/Nazara/Core/Posix/DirectoryImpl.hpp @@ -0,0 +1,48 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_DIRECTORYIMPL_HPP +#define NAZARA_DIRECTORYIMPL_HPP + +#include +#include +#include +#include +#include +#include + +class NzDirectory; +class NzString; + +class NzDirectoryImpl : NzNonCopyable +{ + public: + NzDirectoryImpl(const NzDirectory* parent); + ~NzDirectoryImpl() = default; + + void Close(); + + NzString GetResultName() const; + nzUInt64 GetResultSize() const; + + bool IsResultDirectory() const; + + bool NextResult(); + + bool Open(const NzString& dirPath); + + static bool Create(const NzString& dirPath); + static bool Exists(const NzString& dirPath); + static NzString GetCurrent(); + static bool Remove(const NzString& dirPath); + + private: + DIR* m_handle; + dirent64* m_result; + bool m_firstCall; +}; + +#endif // NAZARA_DIRECTORYIMPL_HPP From 77a87ce2c9ed8225dae772dd0c854630224da6ee Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Fri, 4 Jan 2013 18:30:10 +0100 Subject: [PATCH 11/12] Add Posix hardware infos support. Former-commit-id: adbdeb13349dfea4d962f0df6668f51937803fc4 --- src/Nazara/Core/Posix/HardwareInfoImpl.cpp | 81 ++++++++++++++++++++++ src/Nazara/Core/Posix/HardwareInfoImpl.hpp | 21 ++++++ 2 files changed, 102 insertions(+) create mode 100644 src/Nazara/Core/Posix/HardwareInfoImpl.cpp create mode 100644 src/Nazara/Core/Posix/HardwareInfoImpl.hpp diff --git a/src/Nazara/Core/Posix/HardwareInfoImpl.cpp b/src/Nazara/Core/Posix/HardwareInfoImpl.cpp new file mode 100644 index 000000000..741262239 --- /dev/null +++ b/src/Nazara/Core/Posix/HardwareInfoImpl.cpp @@ -0,0 +1,81 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +#ifdef NAZARA_COMPILER_MSVC +#include +#endif + +#include + +void NzHardwareInfoImpl::Cpuid(nzUInt32 code, nzUInt32 result[4]) +{ + #if defined(NAZARA_COMPILER_MSVC) + __cpuid(reinterpret_cast(result), static_cast(code)); // Visual propose une fonction intrinsèque pour le cpuid + #elif defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL) + // Source: http://stackoverflow.com/questions/1666093/cpuid-implementations-in-c + asm volatile ("cpuid" // Besoin d'être volatile ? + : "=a" (result[0]), "=b" (result[1]), "=c" (result[2]), "=d" (result[3]) // output + : "a" (code), "c" (0)); // input + #else + NazaraInternalError("Cpuid has been called although it is not supported"); + #endif +} + +unsigned int NzHardwareInfoImpl::GetProcessorCount() +{ + // Plus simple (et plus portable) que de passer par le CPUID + return sysconf(_SC_NPROCESSORS_CONF); +} + +bool NzHardwareInfoImpl::IsCpuidSupported() +{ + #ifdef NAZARA_PLATFORM_x64 + return true; // Toujours supporté sur un processeur 64 bits + #else + #if defined(NAZARA_COMPILER_MSVC) + int supported; + __asm + { + pushfd + pop eax + mov ecx, eax + xor eax, 0x200000 + push eax + popfd + pushfd + pop eax + xor eax, ecx + mov supported, eax + push ecx + popfd + }; + + return supported != 0; + #elif defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL) + int supported; + asm volatile (" pushfl\n" + " pop %%eax\n" + " mov %%eax, %%ecx\n" + " xor $0x200000, %%eax\n" + " push %%eax\n" + " popfl\n" + " pushfl\n" + " pop %%eax\n" + " xor %%ecx, %%eax\n" + " mov %%eax, %0\n" + " push %%ecx\n" + " popfl" + : "=m" (supported) // output + : // input + : "eax", "ecx", "memory"); // clobbered register + + return supported != 0; + #else + return false; + #endif + #endif +} diff --git a/src/Nazara/Core/Posix/HardwareInfoImpl.hpp b/src/Nazara/Core/Posix/HardwareInfoImpl.hpp new file mode 100644 index 000000000..feb313d8c --- /dev/null +++ b/src/Nazara/Core/Posix/HardwareInfoImpl.hpp @@ -0,0 +1,21 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_HARDWAREINFOIMPL_POSIX_HPP +#define NAZARA_HARDWAREINFOIMPL_POSIX_HPP + +#include +#include + +class NzHardwareInfoImpl +{ + public: + static void Cpuid(nzUInt32 code, nzUInt32 result[4]); + static unsigned int GetProcessorCount(); + static bool IsCpuidSupported(); +}; + +#endif // NAZARA_HARDWAREINFOIMPL_POSIX_HPP From 9ea78175025b8c28f82a7fbe20510beddc6c90c6 Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Fri, 4 Jan 2013 19:47:16 +0100 Subject: [PATCH 12/12] Little fixes for git. Former-commit-id: 3fac0c3a4402184bfca89fd7e0b954ccbb6bc1da --- src/Nazara/Core/Posix/MutexImpl.cpp | 1 - src/Nazara/Core/Posix/ThreadImpl.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Nazara/Core/Posix/MutexImpl.cpp b/src/Nazara/Core/Posix/MutexImpl.cpp index 81615e71a..96bbd54bb 100644 --- a/src/Nazara/Core/Posix/MutexImpl.cpp +++ b/src/Nazara/Core/Posix/MutexImpl.cpp @@ -7,7 +7,6 @@ NzMutexImpl::NzMutexImpl() { - pthread_mutex_init(&m_handle, NULL); } diff --git a/src/Nazara/Core/Posix/ThreadImpl.cpp b/src/Nazara/Core/Posix/ThreadImpl.cpp index d63fac4c8..383706f1a 100644 --- a/src/Nazara/Core/Posix/ThreadImpl.cpp +++ b/src/Nazara/Core/Posix/ThreadImpl.cpp @@ -11,7 +11,6 @@ NzThreadImpl::NzThreadImpl(NzFunctor* functor) { int error = pthread_create(&m_handle, nullptr, &NzThreadImpl::ThreadProc, functor); - if (error != 0) NazaraInternalError("Failed to create thread: " + NzGetLastSystemError()); }