int main (int argc, char **argv) { struct sembuf buf = {0, 0, 0}; //declaration buf structure int semid = createSem(PATH, PROJECTID, SEMVALUE, IPC_CREAT | WRITEREADATT); //create semaphore switch(fork()) { case -1: //if fork error perror(FORKERROR); exit(1); break; case 0: printData(semid); //print process id and sem data buf.sem_op = CLOSE; // close semaphore if(semop(semid, &buf, 1) == -1) // send cmd { perror(SEMOPERROR); exit(EXIT_FAILURE); } criticalSection(); // do sth printData(semid); //print process id and sem data buf.sem_op = OPEN; // open semaphore if(semop(semid, &buf, 1) == -1) // send cmd { perror(SEMOPERROR); exit(EXIT_FAILURE); } break; default: printData(semid); //print process id and sem data buf.sem_op = CLOSE; // close semaphore if(semop(semid, &buf, 1) == -1) // send cmd { perror(SEMOPERROR); exit(EXIT_FAILURE); } criticalSection(); // do sth printData(semid); //print process id and sem data buf.sem_op = OPEN; // open semaphore if(semop(semid, &buf, 1) == -1) // send cmd { perror(SEMOPERROR); exit(EXIT_FAILURE); } printf(PARENTEND); //end of parent printData(semid); //print process id and sem data if(wait(NULL) == -1) // wait for children { perror(WAITERROR); exit(EXIT_FAILURE); } printf(SEMDELETE, semid); deleteSem(semid); // delete sem break; } return 0; }
void ClientSession::SendCompletion(DWORD transferred) { FastSpinlockGuard criticalSection(mBufferLock); mBuffer.Remove(transferred); mSendBytes += transferred; }
bool ClientSession::PostSend() { if (!IsConnected()) return false; FastSpinlockGuard criticalSection(mBufferLock); if ( 0 == mBuffer.GetContiguiousBytes() ) return true; OverlappedSendContext* sendContext = new OverlappedSendContext(this); DWORD sendbytes = 0; DWORD flags = 0; sendContext->mWsaBuf.len = (ULONG) mBuffer.GetContiguiousBytes(); sendContext->mWsaBuf.buf = mBuffer.GetBufferStart(); /// start async send if (SOCKET_ERROR == WSASend(mSocket, &sendContext->mWsaBuf, 1, &sendbytes, flags, (LPWSAOVERLAPPED)sendContext, NULL)) { if (WSAGetLastError() != WSA_IO_PENDING) { DeleteIoContext(sendContext); printf_s("ClientSession::PostSend Error : %d\n", GetLastError()); return false; } } return true; }
bool ClientSession::PostRecv() { if (!IsConnected()) return false; FastSpinlockGuard criticalSection(mBufferLock); if (0 == mBuffer.GetFreeSpaceSize()) return false; OverlappedRecvContext* recvContext = new OverlappedRecvContext(this); DWORD recvbytes = 0; DWORD flags = 0; recvContext->mWsaBuf.len = (ULONG)mBuffer.GetFreeSpaceSize(); recvContext->mWsaBuf.buf = mBuffer.GetBuffer(); /// start real recv if (SOCKET_ERROR == WSARecv(mSocket, &recvContext->mWsaBuf, 1, &recvbytes, &flags, (LPWSAOVERLAPPED)recvContext, NULL)) { if (WSAGetLastError() != WSA_IO_PENDING) { DeleteIoContext(recvContext); printf_s("ClientSession::PostRecv Error : %d\n", GetLastError()); return false; } } return true; }
void ClientSession::Disconnect(DisconnectReason dr) { FastSpinlockGuard criticalSection(mSessionLock); if ( !IsConnected() ) return ; LINGER lingerOption ; lingerOption.l_onoff = 1; lingerOption.l_linger = 0; /// no TCP TIME_WAIT if (SOCKET_ERROR == setsockopt(mSocket, SOL_SOCKET, SO_LINGER, (char*)&lingerOption, sizeof(LINGER)) ) { printf_s("[DEBUG] setsockopt linger option error: %d\n", GetLastError()); } printf_s("[DEBUG] Client Disconnected: Reason=%d IP=%s, PORT=%d \n", dr, inet_ntoa(mClientAddr.sin_addr), ntohs(mClientAddr.sin_port)); closesocket(mSocket) ; mConnected = false ; mSocket = NULL; ReleaseRef(); }
bool DummyClientSession::SendRequest(short packetType, const protobuf::MessageLite& payload) { if (!IsConnected()) return false; FastSpinlockGuard criticalSection(mSendBufferLock); int totalSize = payload.ByteSize() + HEADER_SIZE; if (mSendBuffer.GetFreeSpaceSize() < totalSize) return false; protobuf::io::ArrayOutputStream arrayOutputStream(mSendBuffer.GetBuffer(), totalSize); protobuf::io::CodedOutputStream codedOutputStream(&arrayOutputStream); PacketHeader header; header.mSize = payload.ByteSize(); header.mType = packetType; codedOutputStream.WriteRaw(&header, HEADER_SIZE); payload.SerializeToCodedStream(&codedOutputStream); /// flush later... LSendRequestSessionList->push_back(this); mSendBuffer.Commit(totalSize); return true; }
bool ClientSession::OnConnect(SOCKET socket, SOCKADDR_IN* addr) { FastSpinlockGuard criticalSection(mSessionLock); CRASH_ASSERT(LIoThreadId == MAIN_THREAD_ID); mSocket = socket; /// make socket non-blocking u_long arg = 1 ; ioctlsocket(mSocket, FIONBIO, &arg) ; /// turn off nagle int opt = 1 ; setsockopt(mSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&opt, sizeof(int)) ; /// create socket RQ /// SEND and RECV within one CQ (you can do with two CQs, seperately) mRequestQueue = RIO.RIOCreateRequestQueue(mSocket, MAX_RECV_RQ_SIZE_PER_SOCKET, 1, MAX_SEND_RQ_SIZE_PER_SOCKET, 1, GRioManager->GetCompletionQueue(mRioThreadId), GRioManager->GetCompletionQueue(mRioThreadId), NULL); if (mRequestQueue == RIO_INVALID_RQ) { printf_s("[DEBUG] RIOCreateRequestQueue Error: %d\n", GetLastError()); return false ; } memcpy(&mClientAddr, addr, sizeof(SOCKADDR_IN)); mConnected = true ; printf_s("[DEBUG] Client Connected: IP=%s, PORT=%d\n", inet_ntoa(mClientAddr.sin_addr), ntohs(mClientAddr.sin_port)); return PostRecv() ; }
void Session::SendCompletion(DWORD transferred) { FastSpinlockGuard criticalSection(mSendBufferLock); mSendBuffer.Remove(transferred); mSendPendingCount--; }
void ClientSession::SendCompletion(DWORD transferred) { mSendBytes += transferred; FastSpinlockGuard criticalSection(mBufferLock); GIocpManager->GSendBytes += sizeof( transferred ); mBuffer.Remove(transferred); }
bool Session::FlushSend() { if (!IsConnected()) { DisconnectRequest(DR_SENDFLUSH_ERROR); return true; } FastSpinlockGuard criticalSection(mSendBufferLock); /// 보낼 데이터가 없는 경우 if (0 == mSendBuffer.GetContiguiousBytes()) { /// 보낼 데이터도 없는 경우 if (0 == mSendPendingCount) return true; return false; } /// 이전의 send가 완료 안된 경우 if (mSendPendingCount > 0) return false; OverlappedSendContext* sendContext = new OverlappedSendContext(this); DWORD sendbytes = 0; DWORD flags = 0; sendContext->mWsaBuf.len = (ULONG)mSendBuffer.GetContiguiousBytes(); sendContext->mWsaBuf.buf = mSendBuffer.GetBufferStart(); /// start async send if (SOCKET_ERROR == WSASend(mSocket, &sendContext->mWsaBuf, 1, &sendbytes, flags, (LPWSAOVERLAPPED)sendContext, NULL)) { if (WSAGetLastError() != WSA_IO_PENDING) { DeleteIoContext(sendContext); printf_s("Session::FlushSend Error : %d\n", GetLastError()); DisconnectRequest(DR_SENDFLUSH_ERROR); return true; } } mSendPendingCount++; return mSendPendingCount == 1; }
void ClientSession::RecvCompletion(DWORD transferred) { FastSpinlockGuard criticalSection(mBufferLock); if ( *( mBuffer.GetBuffer() ) != ( 'a' + ( mSocket % 26 ) ) ) { printf_s( "다른 데이터가 왔다! %c / %c \n", *( mBuffer.GetBuffer() ), 'a' + mSocket % 26 ); } mBuffer.Commit(transferred); mRecvBytes += transferred; mBuffer.GetBuffer(); }
void ClientSession::RecvCompletion(DWORD transferred) { mRecvBytes += transferred; FastSpinlockGuard criticalSection(mBufferLock); GIocpManager->GRecvBytes += sizeof( transferred ); // test code... /* printf_s( "recv: [%d][%d][%d] ", transferred, mSocket % 10, sizeof(transferred) ); if ( transferred == ( mSocket % 10 ) ) { printf_s( " - OK! \n" ); } */ mBuffer.Commit(transferred); }
bool Session::PostSend(const char* data, size_t len) { if (!IsConnected()) return false; FastSpinlockGuard criticalSection(mSendBufferLock); if (mSendBuffer.GetFreeSpaceSize() < len) return false; /// flush later... LSendRequestSessionList->push_back(this); char* destData = mSendBuffer.GetBuffer(); memcpy(destData, data, len); mSendBuffer.Commit(len); return true; }
void producer(semaphore sem_down[], semaphore sem_up[], int mutex, int empty, int full) { int i; //add items to buffer for(i = 0; i < 10; i++) { //delete an empty spot and decrement mutex so CS can't be interrupted semop(empty, sem_down, 1); semop(mutex, sem_down, 1); //Critical section printf("\n\n\n"); printf("About to enter producer's critical section\n"); criticalSection(PROD); printf("Leaving producer's critical section\n"); printf("\n\n\n"); //add full spot and increment mutex so consumer can consume semop(mutex, sem_up, 1); semop(full, sem_up, 1); //experiment with putting delays after this line //sleep(1); } }
void ClientSession::ConnectCompletion() { CRASH_ASSERT( LThreadType == THREAD_IO_WORKER ); if ( 1 == InterlockedExchange( &mConnected, 1 ) ) { /// already exists? CRASH_ASSERT( false ); return; } bool resultOk = true; do { if ( SOCKET_ERROR == setsockopt( mSocket, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0 ) ) { printf_s( "[DEBUG] SO_UPDATE_CONNECT_CONTEXT error: %d\n", GetLastError() ); resultOk = false; break; } int opt = 1; if ( NO_DELAY ) { int opt = 1; if ( SOCKET_ERROR == setsockopt( mSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&opt, sizeof( int ) ) ) { printf_s( "[DEBUG] TCP_NODELAY error: %d\n", GetLastError() ); resultOk = false; break; } } opt = 0; if ( SOCKET_ERROR == setsockopt( mSocket, SOL_SOCKET, SO_RCVBUF, (const char*)&opt, sizeof( int ) ) ) { printf_s( "[DEBUG] SO_RCVBUF change error: %d\n", GetLastError() ); resultOk = false; break; } int addrlen = sizeof( SOCKADDR_IN ); if ( SOCKET_ERROR == getpeername( mSocket, (SOCKADDR*)&mClientAddr, &addrlen ) ) { printf_s( "[DEBUG] getpeername error: %d\n", GetLastError() ); resultOk = false; break; } } while ( false ); if ( !resultOk ) { DisconnectRequest( DR_ONCONNECT_ERROR ); return; } FastSpinlockGuard criticalSection( mBufferLock ); if ( BUFFER_SIZE <= 0 || BUFFER_SIZE > BUFSIZE ) { BUFFER_SIZE = 4096; } char* temp = new char[BUFFER_SIZE]; ZeroMemory( temp, sizeof( char ) * BUFFER_SIZE ); for ( int i = 0; i < BUFFER_SIZE - 1; ++i ) { temp[i] = 'a' + ( mSocket % 26 ); } temp[BUFFER_SIZE - 1] = '\0'; char* bufferStart = mBuffer.GetBuffer(); memcpy( bufferStart, temp, BUFFER_SIZE ); mBuffer.Commit( BUFFER_SIZE ); CRASH_ASSERT( 0 != mBuffer.GetContiguiousBytes() ); OverlappedSendContext* sendContext = new OverlappedSendContext( this ); DWORD sendbytes = 0; DWORD flags = 0; sendContext->mWsaBuf.len = (ULONG)mBuffer.GetContiguiousBytes(); sendContext->mWsaBuf.buf = mBuffer.GetBufferStart(); delete[] temp; /// start async send if ( SOCKET_ERROR == WSASend( mSocket, &sendContext->mWsaBuf, 1, &sendbytes, flags, (LPWSAOVERLAPPED)sendContext, NULL ) ) { if ( WSAGetLastError() != WSA_IO_PENDING ) { DeleteIoContext( sendContext ); printf_s( "ClientSession::PostSend Error : %d\n", GetLastError() ); } } ++mUseCount; }
void ClientSession::RecvCompletion(DWORD transferred) { FastSpinlockGuard criticalSection(mBufferLock); mBuffer.Commit(transferred); }