UINT WINAPI //DWORD WINAPI #elif defined(POSIX_SYS) // using pthread void * #endif ChessRecognition::HoughLineThread( #if defined(WINDOWS_SYS) LPVOID #elif defined(POSIX_SYS) void * #endif Param) { // 실제로 뒤에서 동작하는 windows용 thread함수. // 함수 인자로 클래스를 받아옴. ChessRecognition *_TChessRecognition = (ChessRecognition *)Param; _TChessRecognition->_HoughLineBased = new HoughLineBased(); CvSeq *_TLineX, *_TLineY; double _TH[] = { -1, -7, -15, 0, 15, 7, 1 }; CvMat _TDoGX = cvMat(1, 7, CV_64FC1, _TH); CvMat* _TDoGY = cvCreateMat(7, 1, CV_64FC1); cvTranspose(&_TDoGX, _TDoGY); // transpose(&DoGx) -> DoGy double _TMinValX, _TMaxValX, _TMinValY, _TMaxValY, _TMinValT, _TMaxValT; int _TKernel = 1; // Hough 사용되는 Image에 대한 Initialize. IplImage *iplTemp = cvCreateImage(cvSize(_TChessRecognition->_Width, _TChessRecognition->_Height), IPL_DEPTH_32F, 1); IplImage *iplDoGx = cvCreateImage(cvGetSize(iplTemp), IPL_DEPTH_32F, 1); IplImage *iplDoGy = cvCreateImage(cvGetSize(iplTemp), IPL_DEPTH_32F, 1); IplImage *iplDoGyClone = cvCloneImage(iplDoGy); IplImage *iplDoGxClone = cvCloneImage(iplDoGx); IplImage *iplEdgeX = cvCreateImage(cvGetSize(iplTemp), 8, 1); IplImage *iplEdgeY = cvCreateImage(cvGetSize(iplTemp), 8, 1); CvMemStorage* _TStorageX = cvCreateMemStorage(0), *_TStorageY = cvCreateMemStorage(0); while (_TChessRecognition->_EnableThread != false) { // 이미지를 받아옴. main루프와 동기를 맞추기 위해서 critical section 사용. _TChessRecognition->_ChessBoardDetectionInternalImageProtectMutex.lock(); //EnterCriticalSection(&(_TChessRecognition->cs)); cvConvert(_TChessRecognition->_ChessBoardDetectionInternalImage, iplTemp); //LeaveCriticalSection(&_TChessRecognition->cs); _TChessRecognition->_ChessBoardDetectionInternalImageProtectMutex.unlock(); // 각 X축 Y축 라인을 검출해 내기 위해서 filter 적용. cvFilter2D(iplTemp, iplDoGx, &_TDoGX); // 라인만 축출해내고. cvFilter2D(iplTemp, iplDoGy, _TDoGY); cvAbs(iplDoGx, iplDoGx); cvAbs(iplDoGy, iplDoGy); // 이미지 내부에서 최댓값과 최소값을 구하여 정규화. cvMinMaxLoc(iplDoGx, &_TMinValX, &_TMaxValX); cvMinMaxLoc(iplDoGy, &_TMinValY, &_TMaxValY); cvMinMaxLoc(iplTemp, &_TMinValT, &_TMaxValT); cvScale(iplDoGx, iplDoGx, 2.0 / _TMaxValX); // 정규화. cvScale(iplDoGy, iplDoGy, 2.0 / _TMaxValY); cvScale(iplTemp, iplTemp, 2.0 / _TMaxValT); cvCopy(iplDoGy, iplDoGyClone); cvCopy(iplDoGx, iplDoGxClone); // NMS진행후 추가 작업 _TChessRecognition->_HoughLineBased->NonMaximumSuppression(iplDoGx, iplDoGyClone, _TKernel); _TChessRecognition->_HoughLineBased->NonMaximumSuppression(iplDoGy, iplDoGxClone, _TKernel); cvConvert(iplDoGx, iplEdgeY); // IPL_DEPTH_8U로 다시 재변환. cvConvert(iplDoGy, iplEdgeX); double rho = 1.0; // distance resolution in pixel-related units. double theta = 1.0; // angle resolution measured in radians. int threshold = 20; if (threshold == 0) threshold = 1; // detecting 해낸 edge에서 hough line 검출. _TLineX = cvHoughLines2(iplEdgeX, _TStorageX, CV_HOUGH_STANDARD, 1.0 * rho, CV_PI / 180 * theta, threshold, 0, 0); _TLineY = cvHoughLines2(iplEdgeY, _TStorageY, CV_HOUGH_STANDARD, 1.0 * rho, CV_PI / 180 * theta, threshold, 0, 0); // cvSeq를 vector로 바꾸기 위한 연산. _TChessRecognition->_Vec_ProtectionMutex.lock(); _TChessRecognition->_HoughLineBased->CastSequence(_TLineX, _TLineY); _TChessRecognition->_Vec_ProtectionMutex.unlock(); Sleep(2); } // mat 할당 해제. cvReleaseMat(&_TDoGY); // 내부 연산에 사용된 이미지 할당 해제. cvReleaseImage(&iplTemp); cvReleaseImage(&iplDoGx); cvReleaseImage(&iplDoGy); cvReleaseImage(&iplDoGyClone); cvReleaseImage(&iplDoGxClone); cvReleaseImage(&iplEdgeX); cvReleaseImage(&iplEdgeY); // houghline2에 사용된 opencv 메모리 할당 해제. cvReleaseMemStorage(&_TStorageX); cvReleaseMemStorage(&_TStorageY); delete _TChessRecognition->_HoughLineBased; #if defined(WINDOWS_SYS) _endthread(); #elif defined(POSIX_SYS) #endif _TChessRecognition->_EndThread = true; return 0; }
void NewsSystem_StartCore(void * lpParam){ while(TRUE){ NewsSystem.NewsCore(); } _endthread(); }
/* * ptw32_throw * * All canceled and explicitly exited POSIX threads go through * here. This routine knows how to exit both POSIX initiated threads and * 'implicit' POSIX threads for each of the possible language modes (C, * C++, and SEH). */ void ptw32_throw (DWORD exception) { /* * Don't use pthread_self() to avoid creating an implicit POSIX thread handle * unnecessarily. */ ptw32_thread_t * sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey); #ifdef __CLEANUP_SEH DWORD exceptionInformation[3]; #endif if (exception != PTW32_EPS_CANCEL && exception != PTW32_EPS_EXIT) { /* Should never enter here */ exit (1); } if (NULL == sp || sp->implicit) { /* * We're inside a non-POSIX initialised Win32 thread * so there is no point to jump or throw back to. Just do an * explicit thread exit here after cleaning up POSIX * residue (i.e. cleanup handlers, POSIX thread handle etc). */ void* exitCode = 0; switch (exception) { case PTW32_EPS_CANCEL: exitCode = PTHREAD_CANCELED; break; case PTW32_EPS_EXIT: exitCode = sp->exitStatus; break; } #if defined(PTW32_STATIC_LIB) pthread_win32_thread_detach_np (); #endif #if ! defined (__MINGW32__) || defined (__MSVCRT__) || defined (__DMC__) _endthreadex ((unsigned)exitCode); #else _endthread (); #endif } #ifdef __CLEANUP_SEH exceptionInformation[0] = (DWORD) (exception); exceptionInformation[1] = (DWORD) (0); exceptionInformation[2] = (DWORD) (0); RaiseException (EXCEPTION_PTW32_SERVICES, 0, 3, exceptionInformation); #else /* __CLEANUP_SEH */ #ifdef __CLEANUP_C ptw32_pop_cleanup_all (1); longjmp (sp->start_mark, exception); #else /* __CLEANUP_C */ #ifdef __CLEANUP_CXX switch (exception) { case PTW32_EPS_CANCEL: throw ptw32_exception_cancel (); break; case PTW32_EPS_EXIT: throw ptw32_exception_exit (); break; } #else #error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. #endif /* __CLEANUP_CXX */ #endif /* __CLEANUP_C */ #endif /* __CLEANUP_SEH */ /* Never reached */ }
/** * \return 1 on success, 0 if the function was interrupted and -1 on error */ int stream_enable_cache(stream_t *stream,int64_t size,int64_t min,int64_t seek_limit){ int ss = stream->sector_size ? stream->sector_size : STREAM_BUFFER_SIZE; int res = -1; cache_vars_t* s; if (stream->flags & STREAM_NON_CACHEABLE) { mp_msg(MSGT_CACHE,MSGL_STATUS,"\rThis stream is non-cacheable\n"); return 1; } if (size > SIZE_MAX) { mp_msg(MSGT_CACHE, MSGL_FATAL, "Cache size larger than max. allocation size\n"); return -1; } s=cache_init(size,ss); if(s == NULL) return -1; stream->cache_data=s; s->stream=stream; // callback s->seek_limit=seek_limit; //make sure that we won't wait from cache_fill //more data than it is allowed to fill if (s->seek_limit > s->buffer_size - s->fill_limit ){ s->seek_limit = s->buffer_size - s->fill_limit; } if (min > s->buffer_size - s->fill_limit) { min = s->buffer_size - s->fill_limit; } // to make sure we wait for the cache process/thread to be active // before continuing if (min <= 0) min = 1; #if FORKED_CACHE if((stream->cache_pid=fork())){ if ((pid_t)stream->cache_pid == -1) stream->cache_pid = 0; #else { stream_t* stream2=malloc(sizeof(stream_t)); memcpy(stream2,s->stream,sizeof(stream_t)); s->stream=stream2; #if defined(__MINGW32__) stream->cache_pid = _beginthread( ThreadProc, 0, s ); #elif defined(__OS2__) stream->cache_pid = _beginthread( ThreadProc, NULL, 256 * 1024, s ); #else { pthread_t tid; pthread_create(&tid, NULL, ThreadProc, s); stream->cache_pid = 1; } #endif #endif if (!stream->cache_pid) { mp_msg(MSGT_CACHE, MSGL_ERR, "Starting cache process/thread failed: %s.\n", strerror(errno)); goto err_out; } // wait until cache is filled at least prefill_init % mp_msg(MSGT_CACHE,MSGL_V,"CACHE_PRE_INIT: %"PRId64" [%"PRId64"] %"PRId64" pre:%"PRId64" eof:%d \n", s->min_filepos,s->read_filepos,s->max_filepos,min,s->eof); while(s->read_filepos<s->min_filepos || s->max_filepos-s->read_filepos<min){ /* mp_msg(MSGT_CACHE,MSGL_STATUS,MSGTR_CacheFill, 100.0*(float)(s->max_filepos-s->read_filepos)/(float)(s->buffer_size), s->max_filepos-s->read_filepos ); */ if(s->eof) break; // file is smaller than prefill size if(stream_check_interrupt(PREFILL_SLEEP_TIME)) { res = 0; goto err_out; } } mp_msg(MSGT_CACHE,MSGL_STATUS,"\n"); return 1; // parent exits err_out: cache_uninit(stream); return res; } #if FORKED_CACHE signal(SIGTERM,exit_sighandler); // kill cache_mainloop(s); // make sure forked code never leaves this function exit(0); #endif } #if !FORKED_CACHE #if defined(__MINGW32__) || defined(__OS2__) static void ThreadProc( void *s ){ cache_mainloop(s); _endthread(); }
void CFolderCrawler::WorkerThread() { HANDLE hWaitHandles[2]; hWaitHandles[0] = m_hTerminationEvent; hWaitHandles[1] = m_hWakeEvent; CTGitPath workingPath; bool bFirstRunAfterWakeup = false; DWORD currentTicks = 0; for(;;) { bool bRecursive = !!(DWORD)CRegStdDWORD(_T("Software\\TortoiseGit\\RecursiveOverlay"), TRUE); if (SysInfo::Instance().IsVistaOrLater()) { SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_END); } DWORD waitResult = WaitForMultipleObjects(_countof(hWaitHandles), hWaitHandles, FALSE, INFINITE); // exit event/working loop if the first event (m_hTerminationEvent) // has been signaled or if one of the events has been abandoned // (i.e. ~CFolderCrawler() is being executed) if(m_bRun == false || waitResult == WAIT_OBJECT_0 || waitResult == WAIT_ABANDONED_0 || waitResult == WAIT_ABANDONED_0+1) { // Termination event break; } if (SysInfo::Instance().IsVistaOrLater()) { SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN); } // If we get here, we've been woken up by something being added to the queue. // However, it's important that we don't do our crawling while // the shell is still asking for items bFirstRunAfterWakeup = true; for(;;) { if (!m_bRun) break; // Any locks today? if (CGitStatusCache::Instance().m_bClearMemory) { CGitStatusCache::Instance().WaitToWrite(); CGitStatusCache::Instance().ClearCache(); CGitStatusCache::Instance().Done(); CGitStatusCache::Instance().m_bClearMemory = false; } if(m_lCrawlInhibitSet > 0) { // We're in crawl hold-off ATLTRACE("Crawl hold-off\n"); Sleep(50); continue; } if (bFirstRunAfterWakeup) { Sleep(20); ATLTRACE("Crawl bFirstRunAfterWakeup\n"); bFirstRunAfterWakeup = false; continue; } if ((m_blockReleasesAt < GetTickCount())&&(!m_blockedPath.IsEmpty())) { ATLTRACE(_T("Crawl stop blocking path %s\n"), m_blockedPath.GetWinPath()); m_blockedPath.Reset(); } CGitStatusCache::Instance().RemoveTimedoutBlocks(); if ((m_foldersToUpdate.size() == 0) && (m_pathsToUpdate.size() == 0)) { // Nothing left to do break; } currentTicks = GetTickCount(); if (m_pathsToUpdate.size()) { { AutoLocker lock(m_critSec); m_bPathsAddedSinceLastCrawl = false; workingPath = m_pathsToUpdate.Pop(); if ((!m_blockedPath.IsEmpty()) && (m_blockedPath.IsAncestorOf(workingPath))) { // move the path to the end of the list m_pathsToUpdate.Push(workingPath); if (m_pathsToUpdate.size() < 3) Sleep(50); continue; } } // don't crawl paths that are excluded if (!CGitStatusCache::Instance().IsPathAllowed(workingPath)) continue; if (!CGitStatusCache::Instance().IsPathGood(workingPath)) continue; // check if the changed path is inside an .git folder CString projectroot; if ((workingPath.HasAdminDir(&projectroot)&&workingPath.IsDirectory()) || workingPath.IsAdminDir()) { // we don't crawl for paths changed in a tmp folder inside an .git folder. // Because we also get notifications for those even if we just ask for the status! // And changes there don't affect the file status at all, so it's safe // to ignore notifications on those paths. if (workingPath.IsAdminDir()) { // TODO: add git specific filters here. is there really any change besides index file in .git // that is relevant for overlays? /*CString lowerpath = workingPath.GetWinPathString(); lowerpath.MakeLower(); if (lowerpath.Find(_T("\\tmp\\"))>0) continue; if (lowerpath.Find(_T("\\tmp")) == (lowerpath.GetLength()-4)) continue; if (lowerpath.Find(_T("\\log"))>0) continue;*/ // Here's a little problem: // the lock file is also created for fetching the status // and not just when committing. // If we could find out why the lock file was changed // we could decide to crawl the folder again or not. // But for now, we have to crawl the parent folder // no matter what. //if (lowerpath.Find(_T("\\lock"))>0) // continue; } else if (!workingPath.Exists()) { CGitStatusCache::Instance().WaitToWrite(); CGitStatusCache::Instance().RemoveCacheForPath(workingPath); CGitStatusCache::Instance().Done(); continue; } do { workingPath = workingPath.GetContainingDirectory(); } while(workingPath.IsAdminDir()); ATLTRACE(_T("Invalidating and refreshing folder: %s\n"), workingPath.GetWinPath()); { AutoLocker print(critSec); _stprintf_s(szCurrentCrawledPath[nCurrentCrawledpathIndex], MAX_CRAWLEDPATHSLEN, _T("Invalidating and refreshing folder: %s"), workingPath.GetWinPath()); nCurrentCrawledpathIndex++; if (nCurrentCrawledpathIndex >= MAX_CRAWLEDPATHS) nCurrentCrawledpathIndex = 0; } InvalidateRect(hWnd, NULL, FALSE); CGitStatusCache::Instance().WaitToRead(); // Invalidate the cache of this folder, to make sure its status is fetched again. CCachedDirectory * pCachedDir = CGitStatusCache::Instance().GetDirectoryCacheEntry(workingPath); if (pCachedDir) { git_wc_status_kind status = pCachedDir->GetCurrentFullStatus(); pCachedDir->Invalidate(); if (workingPath.Exists()) { pCachedDir->RefreshStatus(bRecursive); // if the previous status wasn't normal and now it is, then // send a notification too. // We do this here because GetCurrentFullStatus() doesn't send // notifications for 'normal' status - if it would, we'd get tons // of notifications when crawling a working copy not yet in the cache. if ((status != git_wc_status_normal)&&(pCachedDir->GetCurrentFullStatus() != status)) { CGitStatusCache::Instance().UpdateShell(workingPath); ATLTRACE(_T("shell update in crawler for %s\n"), workingPath.GetWinPath()); } } else { CGitStatusCache::Instance().Done(); CGitStatusCache::Instance().WaitToWrite(); CGitStatusCache::Instance().RemoveCacheForPath(workingPath); } } CGitStatusCache::Instance().Done(); //In case that svn_client_stat() modified a file and we got //a notification about that in the directory watcher, //remove that here again - this is to prevent an endless loop AutoLocker lock(m_critSec); m_pathsToUpdate.erase(workingPath); } else if (workingPath.HasAdminDir()) { if (!workingPath.Exists()) { CGitStatusCache::Instance().WaitToWrite(); CGitStatusCache::Instance().RemoveCacheForPath(workingPath); CGitStatusCache::Instance().Done(); continue; } if (!workingPath.Exists()) continue; ATLTRACE(_T("Updating path: %s\n"), workingPath.GetWinPath()); { AutoLocker print(critSec); _stprintf_s(szCurrentCrawledPath[nCurrentCrawledpathIndex], MAX_CRAWLEDPATHSLEN, _T("Updating path: %s"), workingPath.GetWinPath()); nCurrentCrawledpathIndex++; if (nCurrentCrawledpathIndex >= MAX_CRAWLEDPATHS) nCurrentCrawledpathIndex = 0; } InvalidateRect(hWnd, NULL, FALSE); // HasAdminDir() already checks if the path points to a dir DWORD flags = TGITCACHE_FLAGS_FOLDERISKNOWN; flags |= (workingPath.IsDirectory() ? TGITCACHE_FLAGS_ISFOLDER : 0); flags |= (bRecursive ? TGITCACHE_FLAGS_RECUSIVE_STATUS : 0); CGitStatusCache::Instance().WaitToRead(); // Invalidate the cache of folders manually. The cache of files is invalidated // automatically if the status is asked for it and the file times don't match // anymore, so we don't need to manually invalidate those. if (workingPath.IsDirectory()) { CCachedDirectory * cachedDir = CGitStatusCache::Instance().GetDirectoryCacheEntry(workingPath); if (cachedDir) cachedDir->Invalidate(); } CStatusCacheEntry ce = CGitStatusCache::Instance().GetStatusForPath(workingPath, flags); if (ce.GetEffectiveStatus() > git_wc_status_unversioned) { CGitStatusCache::Instance().UpdateShell(workingPath); ATLTRACE(_T("shell update in folder crawler for %s\n"), workingPath.GetWinPath()); } CGitStatusCache::Instance().Done(); AutoLocker lock(m_critSec); m_pathsToUpdate.erase(workingPath); } else { if (!workingPath.Exists()) { CGitStatusCache::Instance().WaitToWrite(); CGitStatusCache::Instance().RemoveCacheForPath(workingPath); CGitStatusCache::Instance().Done(); } } } else if (m_foldersToUpdate.size()) { { AutoLocker lock(m_critSec); m_bItemsAddedSinceLastCrawl = false; // create a new CTSVNPath object to make sure the cached flags are requested again. // without this, a missing file/folder is still treated as missing even if it is available // now when crawling. workingPath = CTGitPath(m_foldersToUpdate.Pop().GetWinPath()); if ((!m_blockedPath.IsEmpty())&&(m_blockedPath.IsAncestorOf(workingPath))) { // move the path to the end of the list m_foldersToUpdate.Push(workingPath); if (m_foldersToUpdate.size() < 3) Sleep(50); continue; } } if (DWORD(workingPath.GetCustomData()) >= currentTicks) { Sleep(50); continue; } if ((!m_blockedPath.IsEmpty())&&(m_blockedPath.IsAncestorOf(workingPath))) continue; if (!CGitStatusCache::Instance().IsPathAllowed(workingPath)) continue; if (!CGitStatusCache::Instance().IsPathGood(workingPath)) continue; ATLTRACE(_T("Crawling folder: %s\n"), workingPath.GetWinPath()); { AutoLocker print(critSec); _stprintf_s(szCurrentCrawledPath[nCurrentCrawledpathIndex], MAX_CRAWLEDPATHSLEN, _T("Crawling folder: %s"), workingPath.GetWinPath()); nCurrentCrawledpathIndex++; if (nCurrentCrawledpathIndex >= MAX_CRAWLEDPATHS) nCurrentCrawledpathIndex = 0; } InvalidateRect(hWnd, NULL, FALSE); CGitStatusCache::Instance().WaitToRead(); // Now, we need to visit this folder, to make sure that we know its 'most important' status CCachedDirectory * cachedDir = CGitStatusCache::Instance().GetDirectoryCacheEntry(workingPath.GetDirectory()); // check if the path is monitored by the watcher. If it isn't, then we have to invalidate the cache // for that path and add it to the watcher. if (!CGitStatusCache::Instance().IsPathWatched(workingPath)) { if (workingPath.HasAdminDir()) { ATLTRACE(_T("Add watch path %s\n"), workingPath.GetWinPath()); CGitStatusCache::Instance().AddPathToWatch(workingPath); } if (cachedDir) cachedDir->Invalidate(); else { CGitStatusCache::Instance().Done(); CGitStatusCache::Instance().WaitToWrite(); CGitStatusCache::Instance().RemoveCacheForPath(workingPath); } } if (cachedDir) cachedDir->RefreshStatus(bRecursive); #if 0 // While refreshing the status, we could get another crawl request for the same folder. // This can happen if the crawled folder has a lower status than one of the child folders // (recursively). To avoid double crawlings, remove such a crawl request here AutoLocker lock(m_critSec); if (m_bItemsAddedSinceLastCrawl) { m_foldersToUpdate.erase(workingPath); } #endif CGitStatusCache::Instance().Done(); } } } _endthread(); }
/* For better readability we use a separate function to implement the child code of sock_get_address_info_async. Note, that under W32 this is actually not a child but a thread and this is the reason why we pass only a void pointer. */ static void address_info_async_child(void *opaque) { SockLookupData *parm = opaque; #ifdef INET6 gint gai_err; struct addrinfo hints, *res, *ai; gchar port_str[6]; #else /* !INET6 */ struct hostent *hp; gchar **addr_list_p; struct sockaddr_in ad; #endif /* INET6 */ gint ai_member[4] = {AF_UNSPEC, 0, 0, 0}; #ifndef G_OS_WIN32 close(parm->pipe_fds[0]); parm->pipe_fds[0] = -1; #endif #ifdef INET6 memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; g_snprintf(port_str, sizeof(port_str), "%d", parm->port); gai_err = getaddrinfo(parm->hostname, port_str, &hints, &res); if (gai_err != 0) { gchar len = 0; g_warning("getaddrinfo for %s:%s failed: %s\n", parm->hostname, port_str, gai_strerror(gai_err)); log_error(LOG_PROTOCOL, _("%s:%s: host lookup failed (%s).\n"), parm->hostname, port_str, gai_strerror(gai_err)); fd_write_all(parm->pipe_fds[1], &len, sizeof(len)); fd_write_all(parm->pipe_fds[1], (gchar *)ai_member, sizeof(ai_member)); close(parm->pipe_fds[1]); parm->pipe_fds[1] = -1; #ifdef G_OS_WIN32 _endthread(); #else _exit(1); #endif } if (res != NULL) { if (res->ai_canonname && strlen(res->ai_canonname) < 255) { gchar len = strlen(res->ai_canonname); fd_write_all(parm->pipe_fds[1], &len, sizeof(len)); fd_write_all(parm->pipe_fds[1], res->ai_canonname, len); } else { gchar len = 0; fd_write_all(parm->pipe_fds[1], &len, sizeof(len)); } } else { gchar len = 0; fd_write_all(parm->pipe_fds[1], &len, sizeof(len)); } for (ai = res; ai != NULL; ai = ai->ai_next) { ai_member[0] = ai->ai_family; ai_member[1] = ai->ai_socktype; ai_member[2] = ai->ai_protocol; ai_member[3] = ai->ai_addrlen; fd_write_all(parm->pipe_fds[1], (gchar *)ai_member, sizeof(ai_member)); fd_write_all(parm->pipe_fds[1], (gchar *)ai->ai_addr, ai->ai_addrlen); } if (res != NULL) freeaddrinfo(res); #else /* !INET6 */ hp = my_gethostbyname(parm->hostname); if (hp == NULL || hp->h_addrtype != AF_INET) { gchar len = 0; fd_write_all(parm->pipe_fds[1], &len, sizeof(len)); fd_write_all(parm->pipe_fds[1], (gchar *)ai_member, sizeof(ai_member)); close(parm->pipe_fds[1]); parm->pipe_fds[1] = -1; #ifdef G_OS_WIN32 _endthread(); #else _exit(1); #endif } ai_member[0] = AF_INET; ai_member[1] = SOCK_STREAM; ai_member[2] = IPPROTO_TCP; ai_member[3] = sizeof(ad); memset(&ad, 0, sizeof(ad)); ad.sin_family = AF_INET; ad.sin_port = htons(parm->port); if (hp->h_name && strlen(hp->h_name) < 255) { gchar len = strlen(hp->h_name); fd_write_all(parm->pipe_fds[1], &len, sizeof(len)); fd_write_all(parm->pipe_fds[1], hp->h_name, len); } else { gchar len = 0; fd_write_all(parm->pipe_fds[1], &len, sizeof(len)); } for (addr_list_p = hp->h_addr_list; *addr_list_p != NULL; addr_list_p++) { memcpy(&ad.sin_addr, *addr_list_p, hp->h_length); fd_write_all(parm->pipe_fds[1], (gchar *)ai_member, sizeof(ai_member)); fd_write_all(parm->pipe_fds[1], (gchar *)&ad, sizeof(ad)); } #endif /* INET6 */ close(parm->pipe_fds[1]); parm->pipe_fds[1] = -1; #ifdef G_OS_WIN32 _endthread(); #else _exit(0); #endif }
//===================================================================== //===================================================================== void _pco_acq_thread_ringBuffer(void *argin) { DEF_FNID; Camera* m_cam = (Camera *) argin; SyncCtrlObj* m_sync = m_cam->_getSyncCtrlObj(); BufferCtrlObj* m_buffer = m_cam->_getBufferCtrlObj(); char _msg[LEN_MSG + 1]; __sprintfSExt(_msg, LEN_MSG, "%s> [ENTRY]", fnId); m_cam->_traceMsg(_msg); m_cam->_sprintComment(true, fnId, "[ENTRY]"); struct stcPcoData *m_pcoData = m_cam->_getPcoData(); TIME_USEC tStart; msElapsedTimeSet(tStart); long long usStart; usElapsedTimeSet(usStart); int error; long msXfer; int requestStop = stopNone; pcoAcqStatus status; HANDLE m_handle = m_cam->getHandle(); m_sync->setAcqFrames(0); // traceAcq m_pcoData->traceAcq.fnId = fnId; double msPerFrame = (m_cam->pcoGetCocRunTime() * 1000.); m_pcoData->traceAcq.msImgCoc = msPerFrame; m_sync->getExpTime(m_pcoData->traceAcq.sExposure); m_sync->getLatTime(m_pcoData->traceAcq.sDelay); m_pcoData->msAcqRec = 0; m_pcoData->msAcqRecTimestamp = getTimestamp(); m_pcoData->traceAcq.usTicks[0].value = usElapsedTime(usStart); m_pcoData->traceAcq.usTicks[0].desc = "before xferImag execTime"; usElapsedTimeSet(usStart); if(m_pcoData->testCmdMode & TESTCMDMODE_PCO2K_XFER_WAITOBJ) { status = (pcoAcqStatus) m_buffer->_xferImag(); // <------------- uses WAITOBJ } else { status = (pcoAcqStatus) m_buffer->_xferImagMult(); // <------------- USES PCO_GetImageEx (NO waitobj) 0x20 } m_pcoData->traceAcq.usTicks[1].value = usElapsedTime(usStart); m_pcoData->traceAcq.usTicks[1].desc = "xferImag execTime"; usElapsedTimeSet(usStart); m_sync->setExposing(status); m_pcoData->traceAcq.usTicks[2].value = usElapsedTime(usStart); m_pcoData->traceAcq.usTicks[2].desc = "sync->setExposing(status) execTime"; usElapsedTimeSet(usStart); //m_sync->stopAcq(); m_pcoData->traceAcq.usTicks[3].value = usElapsedTime(usStart); m_pcoData->traceAcq.usTicks[3].desc = "sync->stopAcq execTime"; usElapsedTimeSet(usStart); const char *msg = m_cam->_pco_SetRecordingState(0, error); m_pcoData->traceAcq.usTicks[4].value = usElapsedTime(usStart); m_pcoData->traceAcq.usTicks[4].desc = "_pco_SetRecordingState execTime"; usElapsedTimeSet(usStart); if(error) { __sprintfSExt(_msg, LEN_MSG, "%s> [%d]> ERROR %s", fnId, __LINE__, msg); m_cam->_traceMsg(_msg); //throw LIMA_HW_EXC(Error, "_pco_SetRecordingState"); } // xfer time m_pcoData->msAcqXfer = m_pcoData->traceAcq.msXfer = m_pcoData->traceAcq.msTotal = msXfer = msElapsedTime(tStart); m_pcoData->traceAcq.endXferTimestamp = m_pcoData->msAcqXferTimestamp = getTimestamp(); __sprintfSExt(_msg, LEN_MSG, "%s> EXIT xfer[%ld] (ms) status[%s]", fnId, msXfer, sPcoAcqStatus[status]); m_cam->_traceMsg(_msg); m_pcoData->traceAcq.usTicks[5].desc = "up to _endtrhead execTime"; m_pcoData->traceAcq.usTicks[5].value = usElapsedTime(usStart); m_sync->setStarted(false); // to test _endthread(); }
void _pco_acq_thread_edge(void *argin) { DEF_FNID; Camera* m_cam = (Camera *) argin; SyncCtrlObj* m_sync = m_cam->_getSyncCtrlObj(); //BufferCtrlObj* m_buffer = m_sync->_getBufferCtrlObj(); BufferCtrlObj* m_buffer = m_cam->_getBufferCtrlObj(); char _msg[LEN_MSG + 1]; __sprintfSExt(_msg, LEN_MSG, "%s> [ENTRY]", fnId); m_cam->_traceMsg(_msg); m_cam->_sprintComment(true, fnId, "[ENTRY]"); struct stcPcoData *m_pcoData = m_cam->_getPcoData(); TIME_USEC tStart; msElapsedTimeSet(tStart); int error; long msXfer; int requestStop = stopNone; pcoAcqStatus status; HANDLE m_handle = m_cam->getHandle(); m_sync->setAcqFrames(0); if(m_pcoData->testCmdMode & TESTCMDMODE_EDGE_XFER) { status = (pcoAcqStatus) m_buffer->_xferImag_getImage_edge(); } else { status = (pcoAcqStatus) m_buffer->_xferImag(); // original } m_sync->setExposing(status); //m_sync->stopAcq(); const char *msg = m_cam->_pco_SetRecordingState(0, error); if(error) { printf("=== %s [%d]> ERROR %s\n", fnId, __LINE__, msg); //throw LIMA_HW_EXC(Error, "_pco_SetRecordingState"); } m_pcoData->traceAcq.fnId = fnId; m_sync->getExpTime(m_pcoData->traceAcq.sExposure); m_sync->getLatTime(m_pcoData->traceAcq.sDelay); m_pcoData->msAcqXfer = msXfer = msElapsedTime(tStart); __sprintfSExt(_msg, LEN_MSG, "%s> [EXIT] xfer[%ld] (ms) status[%s]\n", fnId, msXfer, sPcoAcqStatus[status]); m_cam->_traceMsg(_msg); m_sync->setStarted(false); // updated char *errMsg = NULL; switch(status) { case pcoAcqRecordTimeout: errMsg = "pcoAcqRecordTimeout" ; break; case pcoAcqWaitTimeout: errMsg = "pcoAcqWaitTimeout" ; break; case pcoAcqWaitError: errMsg = "pcoAcqWaitError" ; break; case pcoAcqError: errMsg = "pcoAcqError" ; break; case pcoAcqPcoError: errMsg = "pcoAcqPcoError" ; break; } if(errMsg) { Event *ev = new Event(Hardware,Event::Error,Event::Camera,Event::CamFault, errMsg); m_cam->_getPcoHwEventCtrlObj()->reportEvent(ev); } _endthread(); }
void _pco_acq_thread_dimax_trig_single(void *argin) { DEF_FNID; printf("=== %s [%d]> %s ENTRY\n", fnId, __LINE__,getTimestamp(Iso)); static char msgErr[LEN_ERROR_MSG+1]; int error; int _nrStop; DWORD _dwValidImageCnt, _dwMaxImageCnt; Camera* m_cam = (Camera *) argin; SyncCtrlObj* m_sync = m_cam->_getSyncCtrlObj(); //BufferCtrlObj* m_buffer = m_sync->_getBufferCtrlObj(); BufferCtrlObj* m_buffer = m_cam->_getBufferCtrlObj(); struct stcPcoData *m_pcoData = m_cam->_getPcoData(); m_pcoData->traceAcq.fnId = fnId; m_cam->_sprintComment(true, fnId, "[ENTRY]"); const char *msg; TIME_USEC tStart, tStart0; msElapsedTimeSet(tStart); tStart0 = tStart; long timeout, timeout0, msNowRecordLoop, msRecord, msXfer, msTotal; int nb_acq_frames; int requestStop = stopNone; HANDLE m_handle = m_cam->getHandle(); WORD wSegment; m_cam->_pco_GetActiveRamSegment(wSegment, error); double msPerFrame = (m_cam->pcoGetCocRunTime() * 1000.); m_pcoData->traceAcq.msImgCoc = msPerFrame; //DWORD dwMsSleepOneFrame = (DWORD) (msPerFrame + 0.5); // 4/5 rounding DWORD dwMsSleepOneFrame = (DWORD) (msPerFrame/5.0); // 4/5 rounding if(dwMsSleepOneFrame == 0) dwMsSleepOneFrame = 1; // min sleep bool nb_frames_fixed = false; int nb_frames; m_sync->getNbFrames(nb_frames); //m_pcoData->traceAcq.nrImgRequested = nb_frames; m_pcoData->traceAcq.nrImgRequested0 = nb_frames; m_sync->setAcqFrames(0); timeout = timeout0 = (long) (msPerFrame * (nb_frames * 1.3)); // 30% guard if(timeout < TOUT_MIN_DIMAX) timeout = TOUT_MIN_DIMAX; m_pcoData->traceAcq.msTout = m_pcoData->msAcqTout = timeout; _dwValidImageCnt = 0; m_sync->getExpTime(m_pcoData->traceAcq.sExposure); m_sync->getLatTime(m_pcoData->traceAcq.sDelay); m_sync->setExposing(pcoAcqRecordStart); m_cam->_pco_GetNumberOfImagesInSegment(wSegment, _dwValidImageCnt, _dwMaxImageCnt, error); if(error) { printf("=== %s [%d]> ERROR %s\n", fnId, __LINE__, "_pco_GetNumberOfImagesInSegment"); throw LIMA_HW_EXC(Error, "PCO_GetNumberOfImagesInSegment"); } m_pcoData->dwValidImageCnt[wSegment-1] = m_pcoData->traceAcq.nrImgRecorded = _dwValidImageCnt; m_pcoData->dwMaxImageCnt[wSegment-1] = m_pcoData->traceAcq.maxImgCount = _dwMaxImageCnt; bool doWhile =true; if( ((DWORD) nb_frames > _dwMaxImageCnt) ){ nb_frames_fixed = true; __sprintfSExt(msgErr,LEN_ERROR_MSG, "=== %s [%d]> ERROR INVALID NR FRAMES fixed nb_frames[%d] _dwMaxImageCnt[%d]", fnId, __LINE__, nb_frames, _dwMaxImageCnt); printf("%s\n", msgErr); m_sync->setExposing(pcoAcqError); doWhile = false; } while(doWhile) { WORD wRecState_actual; m_pcoData->msAcqTnow = msNowRecordLoop = msElapsedTime(tStart); m_pcoData->traceAcq.msRecordLoop = msNowRecordLoop; wRecState_actual = m_cam->_pco_GetRecordingState(error); if(error) { printf("=== %s [%d]> ERROR %s\n", fnId, __LINE__, "_pco_GetRecordingState"); throw LIMA_HW_EXC(Error, "PCO_GetRecordingState"); } if(wRecState_actual == 0) break; if((requestStop = m_sync->_getRequestStop(_nrStop)) == stopRequest) { m_sync->_setRequestStop(stopNone); char msg[LEN_TRACEACQ_MSG+1]; //m_buffer->_setRequestStop(stopProcessing); //m_sync->setExposing(pcoAcqStop); snprintf(msg,LEN_TRACEACQ_MSG, "=== %s> STOP REQ (recording). lastImgRec[%d]\n", fnId, _dwValidImageCnt); printf(msg); m_pcoData->traceMsg(msg); break; } Sleep(dwMsSleepOneFrame); // sleep 1 frame } // while(true) m_pcoData->msAcqTnow = msNowRecordLoop = msElapsedTime(tStart); m_pcoData->traceAcq.msRecordLoop = msNowRecordLoop; msg = m_cam->_pco_SetRecordingState(0, error); if(error) { printf("=== %s [%d]> ERROR %s\n", fnId, __LINE__, msg); throw LIMA_HW_EXC(Error, "_pco_SetRecordingState"); } if( (requestStop != stopRequest) && (!nb_frames_fixed)) { if(m_sync->getExposing() == pcoAcqRecordStart) m_sync->setExposing(pcoAcqRecordEnd); m_cam->_pco_GetNumberOfImagesInSegment(wSegment, _dwValidImageCnt, _dwMaxImageCnt, error); if(error) { printf("=== %s [%d]> ERROR %s\n", fnId, __LINE__, msg); throw LIMA_HW_EXC(Error, "PCO_GetNumberOfImagesInSegment"); } m_pcoData->dwValidImageCnt[wSegment-1] = m_pcoData->traceAcq.nrImgRecorded = _dwValidImageCnt; nb_acq_frames = (_dwValidImageCnt < (DWORD) nb_frames) ? _dwValidImageCnt : nb_frames; //m_sync->setAcqFrames(nb_acq_frames); // dimax recording time m_pcoData->msAcqRec = msRecord = msElapsedTime(tStart); m_pcoData->traceAcq.msRecord = msRecord; // loop & stop record m_pcoData->traceAcq.endRecordTimestamp = m_pcoData->msAcqRecTimestamp = getTimestamp(); m_pcoData->traceAcq.nrImgAcquired = nb_acq_frames; m_pcoData->traceAcq.nrImgRequested = nb_frames; msElapsedTimeSet(tStart); // reset for xfer if(nb_acq_frames < nb_frames) m_sync->setNbFrames(nb_acq_frames); // if(m_buffer->_getRequestStop()) { // m_sync->setExposing(pcoAcqStop); // } else // --- in case of stop request during the record phase, the transfer // --- is made to avoid lose the image recorded { pcoAcqStatus status; status = (pcoAcqStatus) m_buffer->_xferImag_getImage(); if(nb_frames_fixed) status = pcoAcqError; m_sync->setExposing(status); } } // if nb_frames_fixed & no stopped //m_sync->setExposing(status); m_pcoData->dwMaxImageCnt[wSegment-1] = m_pcoData->traceAcq.maxImgCount = _dwMaxImageCnt; // traceAcq info - dimax xfer time m_pcoData->msAcqXfer = msXfer = msElapsedTime(tStart); m_pcoData->traceAcq.msXfer = msXfer; m_pcoData->msAcqAll = msTotal = msElapsedTime(tStart0); m_pcoData->traceAcq.msTotal= msTotal; m_pcoData->traceAcq.endXferTimestamp = m_pcoData->msAcqXferTimestamp = getTimestamp(); printf("=== %s [%d]> EXIT nb_frames_requested[%d] _dwValidImageCnt[%d] _dwMaxImageCnt[%d] coc[%g] recLoopTime[%ld] " "tout[(%ld) 0(%ld)] rec[%ld] xfer[%ld] all[%ld](ms)\n", fnId, __LINE__, nb_frames, _dwValidImageCnt, _dwMaxImageCnt, msPerFrame, msNowRecordLoop, timeout, timeout0, msRecord, msXfer, msTotal); // included in 34a8fb6723594919f08cf66759fe5dbd6dc4287e only for dimax (to check for others) m_sync->setStarted(false); #if 0 if(requestStop == stopRequest) { Event *ev = new Event(Hardware,Event::Error,Event::Camera,Event::CamFault, errMsg); m_cam->_getPcoHwEventCtrlObj()->reportEvent(ev); } #endif _endthread(); }