Pool::Entry Pool::tryGet() { std::lock_guard<std::mutex> lock(mutex); initialize(); /// Searching for connection which was established but wasn't used. for (auto & connection : connections) { if (connection->ref_count == 0) { Entry res(connection, this); return res.tryForceConnected() ? res : Entry(); } } /// Throws if pool is overflowed. if (connections.size() >= max_connections) throw Poco::Exception("mysqlxx::Pool is full"); /// Allocates new connection. Connection * conn = allocConnection(true); if (conn) return Entry(conn, this); return Entry(); }
Pool::Entry Pool::Get() { std::unique_lock<std::mutex> lock(mutex); initialize(); for (;;) { for (auto & connection : connections) { if (connection->ref_count == 0) return Entry(connection, this); } if (connections.size() < static_cast<size_t>(max_connections)) { Connection * conn = allocConnection(); if (conn) return Entry(conn, this); } lock.unlock(); ::sleep(MYSQLXX_POOL_SLEEP_ON_CONNECT_FAIL); lock.lock(); } }
/* * For client: connect to the shared memory. Open incoming and * outgoing streams. */ static jint openConnection(SharedMemoryTransport *transport, jlong otherPID, SharedMemoryConnection **connectionPtr) { jint error; SharedMemoryConnection *connection = allocConnection(); if (connection == NULL) { return SYS_NOMEM; } sprintf(connection->name, "%s.%ld", transport->name, sysProcessGetID()); error = sysSharedMemOpen(connection->name, &connection->sharedMemory, &connection->shared); if (error != SYS_OK) { closeConnection(connection); return error; } /* This process is the client */ connection->incoming.shared = &connection->shared->toClient; connection->outgoing.shared = &connection->shared->toServer; error = openStream(&connection->incoming); if (error != SYS_OK) { closeConnection(connection); return error; } error = openStream(&connection->outgoing); if (error != SYS_OK) { closeConnection(connection); return error; } error = sysProcessOpen(otherPID, &connection->otherProcess); if (error != SYS_OK) { fprintf(stderr,"Error accessing process, rc = %d\n", error); closeConnection(connection); return error; } /* * Create an event that signals that the connection is shutting * down. The event is unnamed as it's process local, and is * manually reset (so that signalling the event will signal * all threads waiting on it). */ error = sysEventCreate(NULL, &connection->shutdown, JNI_TRUE); if (error != SYS_OK) { fprintf(stderr,"Error creating unnamed event, rc = %d\n", error); closeConnection(connection); return error; } *connectionPtr = connection; return SYS_OK; }
void Pool::initialize() { if (!initialized) { description = db + "@" + server + ":" + Poco::NumberFormatter::format(port) + " as user " + user; for (unsigned i = 0; i < default_connections; ++i) allocConnection(); initialized = true; } }
PAPIConnection * newConnection( PAPIConnectionListener inConnectionListener, void * inUserData, PAPIListener inInternalListener, void * inInternalListenerData, PAPIStatus * outStatus ) { PAPIStatus theStatus; PAPIConnection * theConnection = 0; int theSocket = daemonConnect( 10 ); if ( theSocket == INVALID_SOCKET ) { *outStatus = PAPIConnectionFailure; } else { *outStatus = PAPISuccess; } if ( *outStatus == PAPISuccess || isDaemonEnabled() == 1 ) { theConnection = allocConnection( inConnectionListener, inUserData, inInternalListener, inInternalListenerData, theSocket, &theStatus ); if ( theStatus == PAPISuccess ) { startListeningThread( theConnection, &theStatus ); } if ( theStatus != PAPISuccess ) { deleteConnection( theConnection ); theConnection = 0; *outStatus = theStatus; } } return theConnection; }
/* * For server: create the shared memory. Create incoming and * outgoing streams. */ static jint createConnection(SharedMemoryTransport *transport, jlong otherPID, SharedMemoryConnection **connectionPtr) { jint error; char streamPrefix[MAX_IPC_NAME]; SharedMemoryConnection *connection = allocConnection(); if (connection == NULL) { return SYS_NOMEM; } sprintf(connection->name, "%s.%ld", transport->name, otherPID); error = sysSharedMemCreate(connection->name, sizeof(SharedMemory), &connection->sharedMemory, &connection->shared); if (error != SYS_OK) { closeConnection(connection); return error; } memset(connection->shared, 0, sizeof(SharedMemory)); /* This process is the server */ connection->incoming.shared = &connection->shared->toServer; connection->outgoing.shared = &connection->shared->toClient; strcpy(streamPrefix, connection->name); strcat(streamPrefix, ".ctos"); error = createStream(streamPrefix, &connection->incoming); if (error != SYS_OK) { closeConnection(connection); return error; } strcpy(streamPrefix, connection->name); strcat(streamPrefix, ".stoc"); error = createStream(streamPrefix, &connection->outgoing); if (error != SYS_OK) { closeConnection(connection); return error; } error = sysProcessOpen(otherPID, &connection->otherProcess); if (error != SYS_OK) { fprintf(stderr,"Error accessing process, rc = %d\n", error); closeConnection(connection); return error; } /* * Create an event that signals that the connection is shutting * down. The event is unnamed as it's process local, and is * manually reset (so that a signalling the event will signal * all threads waiting on it). */ error = sysEventCreate(NULL, &connection->shutdown, JNI_TRUE); if (error != SYS_OK) { fprintf(stderr,"Error creating unnamed event, rc = %d\n", error); closeConnection(connection); return error; } *connectionPtr = connection; return SYS_OK; }