static void _start_thread(SG_context * pCtx, void* pFunc, void* pParam, pthread_t* pThreadId) // pCtx: input parameter only (used for logging) { pthread_t thread_id; // pthread_attr_t attr; int retval; // (void) pthread_attr_init(&attr); // (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); retval = pthread_create(&thread_id, NULL, pFunc, pParam); if (retval) SG_ERR_THROW2_RETURN(SG_ERR_ERRNO(retval), (pCtx, "%s", "pthread_create failed")); *pThreadId = thread_id; }
void SG_time__get_milliseconds_since_1970_utc(SG_context* pCtx, SG_int64* pResult) { struct timeval tv; SG_int64 result; int rc; rc = gettimeofday(&tv, NULL); if (rc) { *pResult = 0; SG_ERR_THROW_RETURN( SG_ERR_ERRNO(errno) ); } result = (SG_int64) tv.tv_sec; result *= MILLISECONDS_PER_SECOND; result += (tv.tv_usec / 1000); *pResult = result; }
static void send_upload_request( SG_context* pCtx, CFHTTPMessageRef myRequest, CFReadStreamRef upload, CFReadStreamRef* pp ) { CFReadStreamRef myReadStream = NULL; myReadStream = CFReadStreamCreateForStreamedHTTPRequest(kCFAllocatorDefault, myRequest, upload); if (!CFReadStreamOpen(myReadStream)) { CFStreamError myErr = CFReadStreamGetError(myReadStream); if (myErr.domain == kCFStreamErrorDomainPOSIX) { // Interpret myErr.error as a UNIX errno. SG_ERR_THROW( SG_ERR_ERRNO(myErr.error) ); } else if (myErr.domain == kCFStreamErrorDomainMacOSStatus) { // Interpret myErr.error as a MacOS error code. // TODO SG_ERR_THROW( SG_ERR_MAC((OSStatus) myErr.error) ); SG_ERR_THROW( SG_ERR_UNSPECIFIED ); } } *pp = myReadStream; myReadStream = NULL; fail: if (myReadStream) { CFReadStreamClose(myReadStream); CFRelease(myReadStream); myReadStream = NULL; } }
void u0038_test_name_conflict(SG_context * pCtx) { thread_data* pThreadData = NULL; SG_closet_descriptor_handle* ph = NULL; SG_vhash* pvh = NULL; SG_closet_descriptor_handle* ph2 = NULL; SG_vhash* pvh2 = NULL; #if defined(WINDOWS) HANDLE hThread = NULL; #else pthread_t thread_id = 0; #endif SG_ERR_IGNORE( SG_closet__descriptors__remove(pCtx, "1") ); SG_ERR_IGNORE( SG_closet__descriptors__remove(pCtx, "2") ); VERIFY_ERR_CHECK( SG_closet__descriptors__add_begin(pCtx, "1", NULL, NULL, NULL, NULL, &pvh, &ph) ); VERIFY_ERR_CHECK( SG_alloc1(pCtx, pThreadData) ); VERIFY_ERR_CHECK( SG_context__alloc__temporary(&pThreadData->pCtx) ); #if defined(WINDOWS) VERIFY_ERR_CHECK( _start_thread(pCtx, _add_conflicting_descriptor_in_thread, pThreadData, &hThread) ); #else VERIFY_ERR_CHECK( _start_thread(pCtx, _add_conflicting_descriptor_in_thread, pThreadData, &thread_id) ); #endif VERIFY_ERR_CHECK( SG_sleep_ms(1000) ); VERIFY_ERR_CHECK( SG_closet__descriptors__add_commit(pCtx, &ph, pvh, SG_REPO_STATUS__NORMAL) ); VERIFY_COND("", !ph); SG_VHASH_NULLFREE(pCtx, pvh); #if defined(WINDOWS) { DWORD dwRet = WaitForSingleObject(hThread, 1000); VERIFY_COND("failure waiting for thread termination", dwRet == WAIT_OBJECT_0); VERIFY_CTX_IS_OK("thread context has error", pThreadData->pCtx); (void) CloseHandle(hThread); } #else { int rc = pthread_join(thread_id, NULL); if (rc) SG_ERR_THROW2(SG_ERR_ERRNO(rc), (pCtx, "%s", "pthread_join failed")); VERIFY_CTX_IS_OK("thread context has error", pThreadData->pCtx); } #endif VERIFY_ERR_CHECK( SG_closet__descriptors__add_begin(pCtx, "2", NULL, NULL, NULL, NULL, &pvh2, &ph2) ); VERIFY_ERR_CHECK( SG_closet__descriptors__add_commit(pCtx, &ph2, pvh2, SG_REPO_STATUS__NORMAL) ); VERIFY_ERR_CHECK_ERR_EQUALS_DISCARD(SG_closet__descriptors__add_begin(pCtx, "1", NULL, NULL, NULL, NULL, &pvh, &ph), SG_ERR_REPO_ALREADY_EXISTS); VERIFY_COND("", !pvh); VERIFY_COND("", !ph); /* fall through */ fail: SG_VHASH_NULLFREE(pCtx, pvh); SG_VHASH_NULLFREE(pCtx, pvh2); SG_ERR_IGNORE(SG_closet__descriptors__add_abort(pCtx, &ph)); SG_ERR_IGNORE(SG_closet__descriptors__add_abort(pCtx, &ph2)); if (pThreadData) { SG_CONTEXT_NULLFREE(pThreadData->pCtx); SG_NULLFREE(pCtx, pThreadData); } SG_ERR_IGNORE( SG_closet__descriptors__remove(pCtx, "1") ); SG_ERR_IGNORE( SG_closet__descriptors__remove(pCtx, "2") ); }
static void perform_upload_request__string( SG_context* pCtx, CFHTTPMessageRef myRequest, SG_pathname* pPath, CFHTTPMessageRef* pmyResponse, SG_string** ppstr ) { CFReadStreamRef myReadStream = NULL; CFHTTPMessageRef myResponse = NULL; SG_string* pstr = NULL; CFReadStreamRef upload = NULL; CFURLRef upload_file_url = NULL; // set the content-length header { SG_uint64 len = 0; SG_ERR_CHECK( SG_fsobj__length__pathname(pCtx, pPath, &len, NULL) ); CFStringRef headerFieldName = CFSTR("Content-Length"); CFStringRef headerFieldValue = CFStringCreateWithFormat (kCFAllocatorDefault, NULL, CFSTR("%d"), len); CFHTTPMessageSetHeaderFieldValue(myRequest, headerFieldName, headerFieldValue); CFRelease(headerFieldValue); } upload_file_url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8*) SG_pathname__sz(pPath), SG_STRLEN(SG_pathname__sz(pPath)), SG_FALSE); upload = CFReadStreamCreateWithFile(kCFAllocatorDefault, upload_file_url); CFRelease(upload_file_url); if (!CFReadStreamOpen(upload)) { CFStreamError myErr = CFReadStreamGetError(upload); if (myErr.domain == kCFStreamErrorDomainPOSIX) { // Interpret myErr.error as a UNIX errno. SG_ERR_THROW( SG_ERR_ERRNO(myErr.error) ); } else if (myErr.domain == kCFStreamErrorDomainMacOSStatus) { // Interpret myErr.error as a MacOS error code. // TODO SG_ERR_THROW( SG_ERR_MAC((OSStatus) myErr.error) ); SG_ERR_THROW( SG_ERR_UNSPECIFIED ); } } SG_ERR_CHECK( send_upload_request(pCtx, myRequest, upload, &myReadStream) ); SG_ERR_CHECK( read_entire_stream__string(pCtx, myReadStream, &pstr, &myResponse) ); *ppstr = pstr; pstr = NULL; *pmyResponse = myResponse; myResponse = NULL; fail: if (upload) { CFRelease(upload); } if (myReadStream) { CFReadStreamClose(myReadStream); CFRelease(myReadStream); myReadStream = NULL; } if (myResponse) { CFRelease(myResponse); myResponse = NULL; } SG_STRING_NULLFREE(pCtx, pstr); }
static void read_entire_stream__string( SG_context* pCtx, CFReadStreamRef myReadStream, SG_string** ppstr, CFHTTPMessageRef* pp ) { SG_string* pstr = NULL; CFHTTPMessageRef myResponse = NULL; CFIndex numBytesRead = 0; SG_ERR_CHECK( SG_string__alloc__sz(pCtx, &pstr, "") ); do { UInt8 buf[8192]; // TODO numBytesRead = CFReadStreamRead(myReadStream, buf, sizeof(buf)); if( numBytesRead > 0 ) { SG_ERR_CHECK( SG_string__append__buf_len(pCtx, pstr, buf, numBytesRead) ); if (!myResponse) { myResponse = (CFHTTPMessageRef)CFReadStreamCopyProperty(myReadStream, kCFStreamPropertyHTTPResponseHeader); } } else if( numBytesRead < 0 ) { CFStreamError myErr = CFReadStreamGetError(myReadStream); // TODO clean this up if (myErr.domain == kCFStreamErrorDomainPOSIX) { if (ETIMEDOUT == myErr.error) { usleep(5000); numBytesRead = 0; } else { // Interpret myErr.error as a UNIX errno. SG_ERR_THROW( SG_ERR_ERRNO(myErr.error) ); } } else if (myErr.domain == kCFStreamErrorDomainMacOSStatus) { // Interpret myErr.error as a MacOS error code. // TODO SG_ERR_THROW( SG_ERR_MAC((OSStatus) myErr.error) ); SG_ERR_THROW( SG_ERR_UNSPECIFIED ); } } } while( numBytesRead > 0 ); if (!myResponse) { myResponse = (CFHTTPMessageRef)CFReadStreamCopyProperty(myReadStream, kCFStreamPropertyHTTPResponseHeader); } *pp = myResponse; myResponse = NULL; *ppstr = pstr; pstr = NULL; fail: if (myResponse) { CFRelease(myResponse); } SG_STRING_NULLFREE(pCtx, pstr); }
static void read_entire_stream__file( SG_context* pCtx, CFReadStreamRef myReadStream, SG_pathname* pPath, CFHTTPMessageRef* pp, SG_bool b_progress ) { CFHTTPMessageRef myResponse = NULL; CFIndex numBytesRead = 0; SG_file* pFile = NULL; SG_int64 content_length = 0; SG_int64 so_far = 0; SG_ERR_CHECK( SG_file__open__pathname(pCtx, pPath, SG_FILE_CREATE_NEW | SG_FILE_WRONLY, 0644, &pFile) ); do { UInt8 buf[8192]; // TODO numBytesRead = CFReadStreamRead(myReadStream, buf, sizeof(buf)); if( numBytesRead > 0 ) { SG_ERR_CHECK( SG_file__write(pCtx, pFile, numBytesRead, buf, NULL) ); if (!myResponse) { myResponse = (CFHTTPMessageRef)CFReadStreamCopyProperty(myReadStream, kCFStreamPropertyHTTPResponseHeader); CFStringRef contentLengthString = CFHTTPMessageCopyHeaderFieldValue(myResponse, CFSTR("Content-Length")); if (contentLengthString) { // TODO 32 bit limit problem here content_length = CFStringGetIntValue(contentLengthString); CFRelease(contentLengthString); } if (b_progress) { SG_ERR_CHECK( SG_log__set_steps(pCtx, content_length / 1024, "KB") ); } } so_far += (SG_uint32) numBytesRead; if (b_progress) { SG_ERR_CHECK( SG_log__set_finished(pCtx, so_far / 1024) ); } } else if( numBytesRead < 0 ) { CFStreamError myErr = CFReadStreamGetError(myReadStream); // TODO clean this up if (myErr.domain == kCFStreamErrorDomainPOSIX) { if (ETIMEDOUT == myErr.error) { usleep(5000); numBytesRead = 0; } else { // Interpret myErr.error as a UNIX errno. SG_ERR_THROW( SG_ERR_ERRNO(myErr.error) ); } } else if (myErr.domain == kCFStreamErrorDomainMacOSStatus) { // Interpret myErr.error as a MacOS error code. // TODO SG_ERR_THROW( SG_ERR_MAC((OSStatus) myErr.error) ); SG_ERR_THROW( SG_ERR_UNSPECIFIED ); } } } while( numBytesRead > 0 ); SG_ERR_CHECK( SG_file__close(pCtx, &pFile) ); if (!myResponse) { myResponse = (CFHTTPMessageRef)CFReadStreamCopyProperty(myReadStream, kCFStreamPropertyHTTPResponseHeader); } *pp = myResponse; myResponse = NULL; fail: if (pFile) { SG_ERR_CHECK( SG_file__close(pCtx, &pFile) ); // TODO delete it too } if (myResponse) { CFRelease(myResponse); } }