diff options
Diffstat (limited to 'src/3rdParty/efsw/platform/posix/SystemImpl.cpp')
-rwxr-xr-x | src/3rdParty/efsw/platform/posix/SystemImpl.cpp | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/src/3rdParty/efsw/platform/posix/SystemImpl.cpp b/src/3rdParty/efsw/platform/posix/SystemImpl.cpp new file mode 100755 index 0000000..37d4120 --- /dev/null +++ b/src/3rdParty/efsw/platform/posix/SystemImpl.cpp | |||
@@ -0,0 +1,168 @@ | |||
1 | #include <efsw/platform/posix/SystemImpl.hpp> | ||
2 | |||
3 | #if defined( EFSW_PLATFORM_POSIX ) | ||
4 | |||
5 | #include <cstdio> | ||
6 | #include <limits.h> | ||
7 | #include <pthread.h> | ||
8 | #include <sys/resource.h> | ||
9 | #include <sys/time.h> | ||
10 | |||
11 | #include <efsw/Debug.hpp> | ||
12 | #include <efsw/FileSystem.hpp> | ||
13 | |||
14 | #if EFSW_OS == EFSW_OS_MACOSX | ||
15 | #include <CoreFoundation/CoreFoundation.h> | ||
16 | #elif EFSW_OS == EFSW_OS_LINUX || EFSW_OS == EFSW_OS_ANDROID | ||
17 | #include <libgen.h> | ||
18 | #include <unistd.h> | ||
19 | #elif EFSW_OS == EFSW_OS_HAIKU | ||
20 | #include <kernel/OS.h> | ||
21 | #include <kernel/image.h> | ||
22 | #elif EFSW_OS == EFSW_OS_SOLARIS | ||
23 | #include <stdlib.h> | ||
24 | #elif EFSW_OS == EFSW_OS_BSD | ||
25 | #include <sys/sysctl.h> | ||
26 | #endif | ||
27 | |||
28 | namespace efsw { namespace Platform { | ||
29 | |||
30 | void System::sleep( const unsigned long& ms ) { | ||
31 | // usleep( static_cast<unsigned long>( ms * 1000 ) ); | ||
32 | |||
33 | // usleep is not reliable enough (it might block the | ||
34 | // whole process instead of just the current thread) | ||
35 | // so we must use pthread_cond_timedwait instead | ||
36 | |||
37 | // this implementation is inspired from Qt | ||
38 | // and taken from SFML | ||
39 | |||
40 | unsigned long long usecs = ms * 1000; | ||
41 | |||
42 | // get the current time | ||
43 | timeval tv; | ||
44 | gettimeofday( &tv, NULL ); | ||
45 | |||
46 | // construct the time limit (current time + time to wait) | ||
47 | timespec ti; | ||
48 | ti.tv_nsec = ( tv.tv_usec + ( usecs % 1000000 ) ) * 1000; | ||
49 | ti.tv_sec = tv.tv_sec + ( usecs / 1000000 ) + ( ti.tv_nsec / 1000000000 ); | ||
50 | ti.tv_nsec %= 1000000000; | ||
51 | |||
52 | // create a mutex and thread condition | ||
53 | pthread_mutex_t mutex; | ||
54 | pthread_mutex_init( &mutex, 0 ); | ||
55 | pthread_cond_t condition; | ||
56 | pthread_cond_init( &condition, 0 ); | ||
57 | |||
58 | // wait... | ||
59 | pthread_mutex_lock( &mutex ); | ||
60 | pthread_cond_timedwait( &condition, &mutex, &ti ); | ||
61 | pthread_mutex_unlock( &mutex ); | ||
62 | |||
63 | // destroy the mutex and condition | ||
64 | pthread_cond_destroy( &condition ); | ||
65 | } | ||
66 | |||
67 | std::string System::getProcessPath() { | ||
68 | #if EFSW_OS == EFSW_OS_MACOSX | ||
69 | char exe_file[FILENAME_MAX + 1]; | ||
70 | |||
71 | CFBundleRef mainBundle = CFBundleGetMainBundle(); | ||
72 | |||
73 | if ( mainBundle ) { | ||
74 | CFURLRef mainURL = CFBundleCopyBundleURL( mainBundle ); | ||
75 | |||
76 | if ( mainURL ) { | ||
77 | int ok = CFURLGetFileSystemRepresentation( mainURL, ( Boolean ) true, (UInt8*)exe_file, | ||
78 | FILENAME_MAX ); | ||
79 | |||
80 | if ( ok ) { | ||
81 | return std::string( exe_file ) + "/"; | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | |||
86 | return "./"; | ||
87 | #elif EFSW_OS == EFSW_OS_LINUX | ||
88 | char exe_file[FILENAME_MAX + 1]; | ||
89 | |||
90 | int size; | ||
91 | |||
92 | size = readlink( "/proc/self/exe", exe_file, FILENAME_MAX ); | ||
93 | |||
94 | if ( size < 0 ) { | ||
95 | return std::string( "./" ); | ||
96 | } else { | ||
97 | exe_file[size] = '\0'; | ||
98 | return std::string( dirname( exe_file ) ) + "/"; | ||
99 | } | ||
100 | |||
101 | #elif EFSW_OS == EFSW_OS_BSD | ||
102 | int mib[4]; | ||
103 | mib[0] = CTL_KERN; | ||
104 | mib[1] = KERN_PROC; | ||
105 | mib[2] = KERN_PROC_PATHNAME; | ||
106 | mib[3] = -1; | ||
107 | char buf[1024]; | ||
108 | size_t cb = sizeof( buf ); | ||
109 | sysctl( mib, 4, buf, &cb, NULL, 0 ); | ||
110 | |||
111 | return FileSystem::pathRemoveFileName( std::string( buf ) ); | ||
112 | |||
113 | #elif EFSW_OS == EFSW_OS_SOLARIS | ||
114 | return FileSystem::pathRemoveFileName( std::string( getexecname() ) ); | ||
115 | |||
116 | #elif EFSW_OS == EFSW_OS_HAIKU | ||
117 | image_info info; | ||
118 | int32 cookie = 0; | ||
119 | |||
120 | while ( B_OK == get_next_image_info( 0, &cookie, &info ) ) { | ||
121 | if ( info.type == B_APP_IMAGE ) | ||
122 | break; | ||
123 | } | ||
124 | |||
125 | return FileSystem::pathRemoveFileName( std::string( info.name ) ); | ||
126 | |||
127 | #elif EFSW_OS == EFSW_OS_ANDROID | ||
128 | return "/sdcard/"; | ||
129 | |||
130 | #else | ||
131 | #warning getProcessPath() not implemented on this platform. ( will return "./" ) | ||
132 | return "./"; | ||
133 | |||
134 | #endif | ||
135 | } | ||
136 | |||
137 | void System::maxFD() { | ||
138 | static bool maxed = false; | ||
139 | |||
140 | if ( !maxed ) { | ||
141 | struct rlimit limit; | ||
142 | getrlimit( RLIMIT_NOFILE, &limit ); | ||
143 | limit.rlim_cur = limit.rlim_max; | ||
144 | setrlimit( RLIMIT_NOFILE, &limit ); | ||
145 | |||
146 | getrlimit( RLIMIT_NOFILE, &limit ); | ||
147 | |||
148 | efDEBUG( "File descriptor limit %ld\n", limit.rlim_cur ); | ||
149 | |||
150 | maxed = true; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | Uint64 System::getMaxFD() { | ||
155 | static rlim_t max_fd = 0; | ||
156 | |||
157 | if ( max_fd == 0 ) { | ||
158 | struct rlimit limit; | ||
159 | getrlimit( RLIMIT_NOFILE, &limit ); | ||
160 | max_fd = limit.rlim_cur; | ||
161 | } | ||
162 | |||
163 | return max_fd; | ||
164 | } | ||
165 | |||
166 | }} // namespace efsw::Platform | ||
167 | |||
168 | #endif | ||