MessageQueue* MessageQueue::lookup(Uint32 queueId) { MessageQueue* queue = 0; AutoMutex autoMut(q_table_mut); if (_queueTable.lookup(queueId, queue)) { return queue; } // Not found! Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL3, "MessageQueue::lookup failure queueId = %u", queueId); return 0; }
void MessageQueue::remove(Message* message) { PEG_METHOD_ENTER(TRC_MESSAGEQUEUESERVICE,"MessageQueue::remove()"); if (!message) { PEG_METHOD_EXIT(); throw NullPointer(); } if (message->_owner != this) { PEG_METHOD_EXIT(); throw NoSuchMessageOnQueue(); } { AutoMutex autoMut(_mut); if (message->_next) message->_next->_prev = message->_prev; else _back = message->_prev; if (message->_prev) message->_prev->_next = message->_next; else _front = message->_next; _count--; Tracer::trace(TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL4, "MessageQueue::remove _count = %d", _count); } // mutex unlocks here message->_prev = 0; message->_next = 0; message->_owner = 0; PEG_METHOD_EXIT(); }
void * ModuleController::callback_handle::operator new(size_t size) { if( size != sizeof(callback_handle)) return ::operator new(size); AutoMutex autoMut(_alloc_mut); callback_handle *node = _head; if(node) _head = reinterpret_cast<callback_handle *>(node->_parm); else { callback_handle *block = reinterpret_cast<callback_handle *>(::operator new(BLOCK_SIZE * sizeof(callback_handle))); int i; for(i = 1; i < BLOCK_SIZE - 1; ++i) block[i]._parm = & block[i + 1]; block[BLOCK_SIZE - 1]._parm = NULL; node = block; _head = &block[1]; } return node; }
MessageQueue* MessageQueue::lookup(const char *name) { if (name == NULL) throw NullPointer(); AutoMutex autoMut(q_table_mut); for (QueueTable::Iterator i = _queueTable.start(); i; i++) { // ATTN: Need to decide how many characters to compare in queue names if (!strcmp(((MessageQueue *)i.value())->getQueueName(), name)) { return (MessageQueue *)i.value(); } } PEG_TRACE((TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL1, "MessageQueue::lookup failure - name = %s", name)); return 0; }
MessageQueue::~MessageQueue() { // ATTN-A: thread safety! PEG_METHOD_ENTER(TRC_MESSAGEQUEUESERVICE,"MessageQueue::~MessageQueue()"); PEG_TRACE((TRC_MESSAGEQUEUESERVICE, Tracer::LEVEL3, "MessageQueue::~MessageQueue queueId = %i, name = %s", _queueId, _name)); { AutoMutex autoMut(q_table_mut); _queueTable.remove(_queueId); } // mutex unlocks here // Free the name: delete [] _name; // Return the queue id. putQueueId(_queueId); PEG_METHOD_EXIT(); }
// Creates a SNMP session void snmpDeliverTrap_netsnmp::_createSession( const String& targetHost, Uint16 targetHostFormat, Uint32 portNumber, const String& securityName, void*& sessionHandle, snmp_session*& sessionPtr) { PEG_METHOD_ENTER(TRC_IND_HANDLER, "snmpDeliverTrap_netsnmp::_createSession"); Sint32 libErr, sysErr; char* errStr; String exceptionStr; struct snmp_session snmpSession; { AutoMutex autoMut(_sessionInitMutex); snmp_sess_init(&snmpSession); CString targetHostCStr = targetHost.getCString(); // peername has format: targetHost:portNumber snmpSession.peername = (char*)malloc((size_t)(strlen(targetHostCStr) + 1 + 32)); if (targetHostFormat == _IPV6_ADDRESS) { sprintf(snmpSession.peername, "udp6:[%s]:%u", (const char*)targetHostCStr, portNumber); } else { sprintf(snmpSession.peername, "%s:%u", (const char*)targetHostCStr, portNumber); } sessionHandle = snmp_sess_open(&snmpSession); } if (sessionHandle == NULL) { exceptionStr = _MSG_SESSION_OPEN_FAILED; // Get library, system errno snmp_error(&snmpSession, &libErr, &sysErr, &errStr); exceptionStr.append(errStr); free(errStr); free(snmpSession.peername); PEG_METHOD_EXIT(); throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms(_MSG_SESSION_OPEN_FAILED_KEY, exceptionStr)); } try { // get the snmp_session pointer sessionPtr = snmp_sess_session(sessionHandle); if (sessionPtr == NULL) { exceptionStr = _MSG_GET_SESSION_POINT_FAILED; // Get library, system errno snmp_sess_error(&snmpSession, &libErr, &sysErr, &errStr); exceptionStr.append(errStr); free(errStr); free(snmpSession.peername); throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms( _MSG_GET_SESSION_POINTER_FAILED_KEY, exceptionStr)); } // Community Name, default is public String communityName; if (securityName.size() == 0) { communityName.assign("public"); } else { communityName = securityName; } free(snmpSession.peername); free(sessionPtr->community); CString communityNameCStr = communityName.getCString(); size_t communityNameLen = strlen(communityNameCStr); sessionPtr->community = (u_char*)malloc(communityNameLen); memcpy(sessionPtr->community, (const char*)communityNameCStr, communityNameLen); sessionPtr->community_len = communityNameLen; } catch (...) { _destroySession(sessionHandle); PEG_METHOD_EXIT(); throw; } PEG_METHOD_EXIT(); }
void HTTPAcceptor::_acceptConnection() { // This function cannot be called on an invalid socket! PEGASUS_ASSERT(_rep != 0); // Accept the connection (populate the address): struct sockaddr* accept_address; SocketLength address_size; if (_connectionType == LOCAL_CONNECTION) { #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET accept_address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_un); address_size = sizeof(struct sockaddr_un); #else PEGASUS_ASSERT(false); #endif } else { #ifdef PEGASUS_ENABLE_IPV6 accept_address = reinterpret_cast<struct sockaddr*> (new struct sockaddr_storage); address_size = sizeof(struct sockaddr_storage); #else accept_address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_in); address_size = sizeof(struct sockaddr_in); #endif } // It is not necessary to handle EINTR errors from this accept() call. // An EINTR error should not occur on a non-blocking socket. If the // listen socket is blocking and EINTR occurs, the new socket connection // is not accepted here. // EAGAIN errors are also not handled here. An EAGAIN error should not // occur after select() indicates that the listen socket is available for // reading. If the accept() fails with an EAGAIN error code, a new // connection is not accepted here. SocketHandle socket = accept(_rep->socket, accept_address, &address_size); if (socket == PEGASUS_SOCKET_ERROR) { // the remote connection is invalid, destroy client address. delete accept_address; // TCPIP is down reconnect this acceptor if (getSocketError() == PEGASUS_NETWORK_TCPIP_STOPPED) { PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, "Socket has an IO error. TCP/IP down. Try to reconnect."); reconnectConnectionSocket(); return; } PEG_TRACE(( TRC_DISCARDED_DATA, Tracer::LEVEL1, "HTTPAcceptor: accept() failed. errno: %u", errno)); return; } // Use an AutoPtr to ensure the socket handle is closed on exception AutoPtr<SocketHandle, CloseSocketHandle> socketPtr(&socket); #ifndef PEGASUS_OS_TYPE_WINDOWS // We need to ensure that the socket number is not higher than // what fits into FD_SETSIZE, because we else won't be able to select on it // and won't ever communicate correct on that socket. if (socket >= FD_SETSIZE) { // the remote connection is invalid, destroy client address. delete accept_address; PEG_TRACE( (TRC_DISCARDED_DATA, Tracer::LEVEL1, "HTTPAcceptor out of available sockets." "accept() returned too large socket number %u." "Closing connection to the new client.", socket)); return; } #endif String ipAddress; if (_connectionType == LOCAL_CONNECTION) { ipAddress = "localhost"; } else { #ifdef PEGASUS_ENABLE_IPV6 char ipBuffer[PEGASUS_INET6_ADDRSTR_LEN]; int rc; if ((rc = System::getNameInfo(accept_address, address_size, ipBuffer, PEGASUS_INET6_ADDRSTR_LEN, 0, 0, NI_NUMERICHOST))) { PEG_TRACE(( TRC_DISCARDED_DATA, Tracer::LEVEL1, "HTTPAcceptor: getnameinfo() failed. rc: %d", rc)); delete accept_address; return; } ipAddress = ipBuffer; #else unsigned char* sa = reinterpret_cast<unsigned char*>( &reinterpret_cast<struct sockaddr_in*>( accept_address)->sin_addr.s_addr); char ipBuffer[32]; sprintf(ipBuffer, "%u.%u.%u.%u", sa[0], sa[1], sa[2], sa[3]); ipAddress = ipBuffer; #endif } delete accept_address; // set the close on exec flag #if !defined(PEGASUS_OS_TYPE_WINDOWS) && !defined(PEGASUS_OS_VMS) int sock_flags; if ((sock_flags = fcntl(socket, F_GETFD, 0)) < 0) { PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, "HTTPAcceptor: fcntl(F_GETFD) failed"); } else { sock_flags |= FD_CLOEXEC; if (fcntl(socket, F_SETFD, sock_flags) < 0) { PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, "HTTPAcceptor: fcntl(F_SETFD) failed"); } } #endif PEG_TRACE(( TRC_HTTP, Tracer::LEVEL3, "HTTPAcceptor - accept() success. Socket: %u", socket)); SharedPtr<MP_Socket> mp_socket(new MP_Socket( socket, _sslcontext, _sslContextObjectLock, ipAddress)); // mp_socket now has responsibility for closing the socket handle socketPtr.release(); mp_socket->disableBlocking(); { #ifndef PEGASUS_INTEGERS_BOUNDARY_ALIGNED AutoMutex lock(_socketWriteTimeoutMutex); #endif mp_socket->setSocketWriteTimeout(_socketWriteTimeout); } // Perform the SSL handshake, if applicable. Sint32 socketAcceptStatus = mp_socket->accept(); if (socketAcceptStatus < 0) { PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, "HTTPAcceptor: SSL_accept() failed"); return; } // Create a new connection and add it to the connection list: AutoPtr<HTTPConnection> connection(new HTTPConnection( _monitor, mp_socket, ipAddress, this, _outputMessageQueue)); if (HTTPConnection::getIdleConnectionTimeout()) { Time::gettimeofday(&connection->_idleStartTime); } if (socketAcceptStatus == 0) { PEG_TRACE_CSTRING(TRC_HTTP, Tracer::LEVEL1, "HTTPAcceptor: SSL_accept() pending"); connection->_acceptPending = true; Time::gettimeofday(&connection->_acceptPendingStartTime); } // Solicit events on this new connection's socket: int index; if (-1 == (index = _monitor->solicitSocketMessages( connection->getSocket(), SocketMessage::READ | SocketMessage::EXCEPTION, connection->getQueueId(), MonitorEntry::TYPE_CONNECTION)) ) { PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, "HTTPAcceptor::_acceptConnection: Attempt to allocate entry in " "_entries table failed."); return; } connection->_entry_index = index; AutoMutex autoMut(_rep->_connection_mut); _rep->connections.append(connection.get()); connection.release(); }
void IndicationOperationAggregate::appendRequest( CIMRequestMessage* request) { AutoMutex autoMut(_appendRequestMutex); _requestList.append(request); }
// // create a file and make a random token data entry to it. // send the file name back to caller // String LocalAuthFile::create() { PEG_METHOD_ENTER(TRC_AUTHENTICATION, "LocalAuthFile::create()"); Uint32 secs, milliSecs; Uint32 mySequenceNumber; System::getCurrentTime(secs, milliSecs); // // extension size is username plus the sequence count // { AutoMutex autoMut(sequenceCountLock); mySequenceNumber = sequenceCount++; } // mutex unlocks here char extension[2*INT_BUFFER_SIZE]; sprintf(extension,"_%u_%u", mySequenceNumber, milliSecs); extension[strlen(extension)] = 0; String filePath; // Check to see whether a domain was specified. If so, strip the domain // from the local auth file name, since the backslash and '@' are invalid // filename characters. Store this in another variable, since we need to // keep the domain around for the rest of the operations. String fileUserName = _userName; Uint32 index = _userName.find('\\'); if (index != PEG_NOT_FOUND) { fileUserName = _userName.subString(index + 1); } else { index = _userName.find('@'); if (index != PEG_NOT_FOUND) { fileUserName = _userName.subString(0, index); } } filePath.append(_authFilePath); filePath.append(fileUserName);//_userName); filePath.append(extension); CString filePathCString = filePath.getCString(); // // 1. Create a file name for authentication. // ofstream outfs(filePathCString); if (!outfs) { // unable to create file Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE, MessageLoaderParms( "Security.Authentication.LocalAuthFile.NO_CREATE", "Creation of the local authentication security file" " $0 failed: $1", filePath, strerror(errno))); PEG_METHOD_EXIT(); throw CannotOpenFile (filePath); } outfs.clear(); // // 2. Set file permission to read/write by the owner only. // #if defined(PEGASUS_OS_TYPE_WINDOWS) Boolean success = FileSystem::changeFilePermissions(filePath, _S_IREAD | _S_IWRITE); #else Boolean success = FileSystem::changeFilePermissions(filePath, S_IRUSR | S_IWUSR); #endif if (!success) { // Unable to change the local auth file permissions, remove the file // and throw CannotOpenFile error. Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE, MessageLoaderParms( "Security.Authentication.LocalAuthFile.NO_CHMOD", "Changing permissions of the local authentication security " "file $0 failed: $1", filePath, strerror(errno))); if (filePath.size()) { if (FileSystem::exists(filePath)) { FileSystem::removeFile(filePath); } } PEG_METHOD_EXIT(); throw CannotOpenFile (filePath); } // // 3. Generate random token and write the token to the file. // String randomToken = _generateRandomTokenString(); outfs << randomToken; // test if the write was successful if (outfs.fail()) { Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE, MessageLoaderParms( "Security.Authentication.LocalAuthFile.NO_WRITE", "Cannot write security token to the local authentication " "security file $0.", filePath)); if (filePath.size()) { if (FileSystem::exists(filePath)) { FileSystem::removeFile(filePath); } } PEG_METHOD_EXIT(); throw CannotOpenFile (filePath); } outfs.close(); // // 4. Set file permission to read only by the owner. // #if defined(PEGASUS_OS_TYPE_WINDOWS) success = FileSystem::changeFilePermissions(filePath, _S_IREAD); #else success = FileSystem::changeFilePermissions(filePath, S_IRUSR); #endif if (!success) { // Unable to change the local auth file permissions, remove the file // and throw CannotOpenFile error. Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE, MessageLoaderParms( "Security.Authentication.LocalAuthFile.NO_CHMOD", "Changing permissions of the local authentication security " "file $0 failed: $1", filePath, strerror(errno))); if (filePath.size()) { if (FileSystem::exists(filePath)) { FileSystem::removeFile(filePath); } } PEG_METHOD_EXIT(); throw CannotOpenFile (filePath); } // // 5. Change the file owner to the requesting user. // if (!FileSystem::changeFileOwner(filePath,_userName)) { // Unable to change owner on local auth file, remove the file // and throw CannotOpenFile error. Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE, MessageLoaderParms( "Security.Authentication.LocalAuthFile.NO_CHOWN_REQUSER", "Changing ownership of the local authentication " "security file $0 to the requesting user failed: $1", filePath, strerror(errno))); if (filePath.size()) { if (FileSystem::exists(filePath)) { FileSystem::removeFile(filePath); } } PEG_METHOD_EXIT(); throw CannotOpenFile (filePath); } _secret = randomToken; _filePathName = filePath; PEG_METHOD_EXIT(); return _filePathName; }
void StatisticalData::addToValue(Sint64 value, MessageType msgType, StatDataType t) { // Map MessageType to statistic type. Requires multiple tests because // mapping request and responses to the request types. Uint16 type; if ((msgType) >= CIM_OPEN_ENUMERATE_INSTANCES_REQUEST_MESSAGE) { type = msgType - CIM_DELETE_QUALIFIER_RESPONSE_MESSAGE; } else if (msgType >= CIM_GET_CLASS_RESPONSE_MESSAGE) { type = msgType - CIM_GET_CLASS_RESPONSE_MESSAGE; } else { type = msgType - 1; } // Test if valid statistic type if (type >= NUMBER_OF_TYPES) { PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL2, "StatData: Statistical Data Discarded. " "Invalid Request Type = %u", type)); return; } //// Diagnostic to confirm message type conversion. Normally commented //// out // PEG_TRACE((TRC_STATISTICAL_DATA, Tracer::LEVEL4, // "StatisticalData::addToValue msgType %s %u. stat type %u %s", // MessageTypeToString(msgType), // msgType, type, (const char*)requestName[type].getCString() )); if (copyGSD) { AutoMutex autoMut(_mutex); switch (t) { case PEGASUS_STATDATA_SERVER: numCalls[type] += 1; cimomTime[type] += value; PEG_TRACE((TRC_STATISTICAL_DATA, Tracer::LEVEL4, "StatData: SERVER: %s(%d): count = %" PEGASUS_64BIT_CONVERSION_WIDTH "d; value = %" PEGASUS_64BIT_CONVERSION_WIDTH "d; total = %" PEGASUS_64BIT_CONVERSION_WIDTH "d", (const char *)requestName[type].getCString(), type, numCalls[type], value, cimomTime[type])); break; case PEGASUS_STATDATA_PROVIDER: providerTime[type] += value; PEG_TRACE((TRC_STATISTICAL_DATA, Tracer::LEVEL4, "StatData: PROVIDER: %s(%d): count = %" PEGASUS_64BIT_CONVERSION_WIDTH "d; value = %" PEGASUS_64BIT_CONVERSION_WIDTH "d; total = %" PEGASUS_64BIT_CONVERSION_WIDTH "d", (const char *)requestName[type].getCString(), type, numCalls[type], value, providerTime[type])); break; case PEGASUS_STATDATA_BYTES_SENT: responseSize[type] += value; PEG_TRACE((TRC_STATISTICAL_DATA, Tracer::LEVEL4, "StatData: BYTES_SENT: %s(%d): count = %" PEGASUS_64BIT_CONVERSION_WIDTH "d; value = %" PEGASUS_64BIT_CONVERSION_WIDTH "d; total = %" PEGASUS_64BIT_CONVERSION_WIDTH "d", (const char *)requestName[type].getCString(), type, numCalls[type], value, responseSize[type])); break; case PEGASUS_STATDATA_BYTES_READ: requestSize[type] += value; PEG_TRACE((TRC_STATISTICAL_DATA, Tracer::LEVEL4, "StatData: BYTES_READ: %s(%d): count = %" PEGASUS_64BIT_CONVERSION_WIDTH "d; value = %" PEGASUS_64BIT_CONVERSION_WIDTH "d; total = %" PEGASUS_64BIT_CONVERSION_WIDTH "d", (const char *)requestName[type].getCString(), type, numCalls[type], value, requestSize[type])); break; } } }
void pegasus_module::module_rep::_send_async_callback(Uint32 msg_handle, Message *msg, void *parm) { AutoMutex autoMut(_thread_safety); _async_callback(msg_handle, msg, parm); }
MessageQueueService::~MessageQueueService() { _die = 1; // The polling_routine locks the _polling_list while // processing the incoming messages for services on the // list. Deleting the service from the _polling_list // prior to processing, avoids synchronization issues // with the _polling_routine. _polling_list.remove(this); // ATTN: The code for closing the _incoming queue // is not working correctly. In OpenPegasus 2.5, // execution of the following code is very timing // dependent. This needs to be fix. // See Bug 4079 for details. if (_incoming_queue_shutdown.value() == 0) { _shutdown_incoming_queue(); } // Wait until all threads processing the messages // for this service have completed. while (_threads.value() > 0) { pegasus_yield(); } { AutoMutex autoMut(_meta_dispatcher_mutex); _service_count--; if (_service_count.value() == 0) { _stop_polling++; _polling_sem.signal(); if (_polling_thread) { _polling_thread->join(); delete _polling_thread; _polling_thread = 0; } _meta_dispatcher->_shutdown_routed_queue(); delete _meta_dispatcher; _meta_dispatcher = 0; delete _thread_pool; _thread_pool = 0; } } // mutex unlocks here // Clean up in case there are extra stuff on the queue. while (_incoming.count()) { try { delete _incoming.remove_first(); } catch (const ListClosed &e) { // If the list is closed, there is nothing we can do. break; } } }
MessageQueueService::MessageQueueService( const char *name, Uint32 queueID, Uint32 capabilities, Uint32 mask) : Base(name, true, queueID), _mask(mask), _die(0), _threads(0), _incoming(true, 0), _incoming_queue_shutdown(0) { _capabilities = (capabilities | module_capabilities::async); _default_op_timeout.tv_sec = 30; _default_op_timeout.tv_usec = 100; max_threads_per_svc_queue = MAX_THREADS_PER_SVC_QUEUE; // if requested threads gt MAX_THREADS_PER_SVC_QUEUE_LIMIT // then set to MAX_THREADS_PER_SVC_QUEUE_LIMIT if (max_threads_per_svc_queue > MAX_THREADS_PER_SVC_QUEUE_LIMIT) { max_threads_per_svc_queue = MAX_THREADS_PER_SVC_QUEUE_LIMIT; } // if requested threads eq 0 (unlimited) // then set to MAX_THREADS_PER_SVC_QUEUE_LIMIT if (max_threads_per_svc_queue == 0) { max_threads_per_svc_queue = MAX_THREADS_PER_SVC_QUEUE_DEFAULT; } // cout << "MAX_THREADS_PER_SVC_QUEUE = " << MAX_THREADS_PER_SVC_QUEUE << endl; // cout << "max_threads_per_svc_queue set to = " << max_threads_per_svc_queue << endl; AutoMutex autoMut(_meta_dispatcher_mutex); if (_meta_dispatcher == 0) { _stop_polling = 0; PEGASUS_ASSERT(_service_count.value() == 0); _meta_dispatcher = new cimom(); if (_meta_dispatcher == NULL) { throw NullPointer(); } // _thread_pool = new ThreadPool(initial_cnt, "MessageQueueService", // minimum_cnt, maximum_cnt, deallocateWait); // _thread_pool = new ThreadPool(0, "MessageQueueService", 0, 0, deallocateWait); } _service_count++; if (false == register_service(name, _capabilities, _mask)) { //l10n //throw BindFailedException("MessageQueueService Base Unable to register with Meta Dispatcher"); MessageLoaderParms parms("Common.MessageQueueService.UNABLE_TO_REGISTER", "MessageQueueService Base Unable to register with Meta Dispatcher"); throw BindFailedException(parms); } _polling_list.insert_last(this); }
void MessageQueue::remove_myself(Uint32 qid) { AutoMutex autoMut(q_table_mut); _queueTable.remove(qid); }