strip added smb:// shares of their user/pass when adding, and instead store that...
[vuplus_xbmc] / xbmc / threads / platform / win / ThreadImpl.cpp
1 /*
2  *      Copyright (C) 2005-2011 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, write to
17  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21
22 #include <windows.h>
23 #include "threads/platform/win/Win32Exception.h"
24
25 void CThread::SpawnThread(unsigned stacksize)
26 {
27   // Create in the suspended state, so that no matter the thread priorities and scheduled order, the handle will be assigned
28   // before the new thread exits.
29   m_ThreadOpaque.handle = CreateThread(NULL, stacksize, (LPTHREAD_START_ROUTINE)&staticThread, this, CREATE_SUSPENDED, &m_ThreadId);
30   if (m_ThreadOpaque.handle == NULL)
31   {
32     if (logger) logger->Log(LOGERROR, "%s - fatal error %d creating thread", __FUNCTION__, GetLastError());
33     return;
34   }
35
36   if (ResumeThread(m_ThreadOpaque.handle) == -1)
37     if (logger) logger->Log(LOGERROR, "%s - fatal error %d resuming thread", __FUNCTION__, GetLastError());
38
39 }
40
41 void CThread::TermHandler()
42 {
43   CloseHandle(m_ThreadOpaque.handle);
44   m_ThreadOpaque.handle = NULL;
45 }
46
47 void CThread::SetThreadInfo()
48 {
49   const unsigned int MS_VC_EXCEPTION = 0x406d1388;
50
51 #pragma pack(push,8)
52   struct THREADNAME_INFO
53   {
54     DWORD dwType; // must be 0x1000
55     LPCSTR szName; // pointer to name (in same addr space)
56     DWORD dwThreadID; // thread ID (-1 caller thread)
57     DWORD dwFlags; // reserved for future use, most be zero
58   } info;
59 #pragma pack(pop)
60
61   info.dwType = 0x1000;
62   info.szName = m_ThreadName.c_str();
63   info.dwThreadID = m_ThreadId;
64   info.dwFlags = 0;
65
66   __try
67   {
68     RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR *)&info);
69   }
70   __except(EXCEPTION_EXECUTE_HANDLER)
71   {
72   }
73 }
74
75 ThreadIdentifier CThread::GetCurrentThreadId()
76 {
77   return ::GetCurrentThreadId();
78 }
79
80 bool CThread::IsCurrentThread(const ThreadIdentifier tid)
81 {
82   return (::GetCurrentThreadId() == tid);
83 }
84
85 int CThread::GetMinPriority(void)
86 {
87   return(THREAD_PRIORITY_IDLE);
88 }
89
90 int CThread::GetMaxPriority(void)
91 {
92   return(THREAD_PRIORITY_HIGHEST);
93 }
94
95 int CThread::GetNormalPriority(void)
96 {
97   return(THREAD_PRIORITY_NORMAL);
98 }
99
100 int CThread::GetSchedRRPriority(void)
101 {
102   return GetNormalPriority();
103 }
104
105 bool CThread::SetPriority(const int iPriority)
106 {
107   bool bReturn = false;
108
109   CSingleLock lock(m_CriticalSection);
110   if (m_ThreadOpaque.handle)
111   {
112     bReturn = SetThreadPriority(m_ThreadOpaque.handle, iPriority) == TRUE;
113   }
114
115   return bReturn;
116 }
117
118 int CThread::GetPriority()
119 {
120   CSingleLock lock(m_CriticalSection);
121
122   int iReturn = THREAD_PRIORITY_NORMAL;
123   if (m_ThreadOpaque.handle)
124   {
125     iReturn = GetThreadPriority(m_ThreadOpaque.handle);
126   }
127   return iReturn;
128 }
129
130 bool CThread::WaitForThreadExit(unsigned int milliseconds)
131 {
132   bool bReturn = true;
133
134   CSingleLock lock(m_CriticalSection);
135   if (m_ThreadId && m_ThreadOpaque.handle != NULL)
136   {
137     // boost priority of thread we are waiting on to same as caller
138     int callee = GetThreadPriority(m_ThreadOpaque.handle);
139     int caller = GetThreadPriority(GetCurrentThread());
140     if(caller > callee)
141       SetThreadPriority(m_ThreadOpaque.handle, caller);
142
143     lock.Leave();
144     bReturn = m_TermEvent.WaitMSec(milliseconds);
145     lock.Enter();
146
147     // restore thread priority if thread hasn't exited
148     if(caller > callee && m_ThreadOpaque.handle)
149       SetThreadPriority(m_ThreadOpaque.handle, callee);
150   }
151   return bReturn;
152 }
153
154 int64_t CThread::GetAbsoluteUsage()
155 {
156   CSingleLock lock(m_CriticalSection);
157
158   if (!m_ThreadOpaque.handle)
159     return 0;
160
161   uint64_t time = 0;
162   FILETIME CreationTime, ExitTime, UserTime, KernelTime;
163   if( GetThreadTimes(m_ThreadOpaque.handle, &CreationTime, &ExitTime, &KernelTime, &UserTime ) )
164   {
165     time = (((uint64_t)UserTime.dwHighDateTime) << 32) + ((uint64_t)UserTime.dwLowDateTime);
166     time += (((uint64_t)KernelTime.dwHighDateTime) << 32) + ((uint64_t)KernelTime.dwLowDateTime);
167   }
168   return time;
169 }
170
171 float CThread::GetRelativeUsage()
172 {
173   unsigned int iTime = XbmcThreads::SystemClockMillis();
174   iTime *= 10000; // convert into 100ns tics
175
176   // only update every 1 second
177   if( iTime < m_iLastTime + 1000*10000 ) return m_fLastUsage;
178
179   int64_t iUsage = GetAbsoluteUsage();
180
181   if (m_iLastUsage > 0 && m_iLastTime > 0)
182     m_fLastUsage = (float)( iUsage - m_iLastUsage ) / (float)( iTime - m_iLastTime );
183
184   m_iLastUsage = iUsage;
185   m_iLastTime = iTime;
186
187   return m_fLastUsage;
188 }
189
190 void CThread::SetSignalHandlers()
191 {
192   // install win32 exception translator
193   win32_exception::install_handler();
194 }