void ThreadHandler::restoreThreads() { int threadCount; out << "Reopening threads\n"; threadCount = settings->value("tabs/count",0).toInt(); QLOG_TRACE() << "ThreadHandler :: restoring Threads"; ImageThread* it; if (threadCount > 0) { for (int i=0; i<threadCount; i++) { it = addThread(); it->setValues( settings->value(QString("tabs/tab%1").arg(i), ";;;;0;;every 30 seconds;;0").toString() ); out << " opening " << it->getUrl() << "\n"; } } else { QLOG_WARN() << "ThreadHandler :: No threads available to restore"; emit threadListEmpty(); } out.flush(); }
int mcreate (void (*start_routine)(void*), void *arg){ assert(start_routine != NULL); initialize(); //Creates the context and initialize it just to get a model ucontext_t newContext; getcontext(&newContext); //The point in which thread will come back when it is finished newContext.uc_link = getTerminateContext(); newContext.uc_stack.ss_sp = malloc(SIGSTKSZ); newContext.uc_stack.ss_size = SIGSTKSZ; makecontext(&newContext, (void(*)())start_routine, 1, arg); Tcb* newThread = createTcb(lastThreadId+1, newContext); //Success if (newThread != NULL){ //Control of ids lastThreadId++; addThread(newThread); changeStateToReady(newThread); return lastThreadId; }else{ return ERR_MCREATE; } }
void ThreadHandler::createThread(QString thread_settings) { ImageThread* it; it = addThread(); it->setValues(thread_settings); out << "Opening thread " << it->getUrl() << "\n"; out.flush(); }
void runRMC () { /* Worker(s) ? */ for (unsigned i = 0; i < my_node -> num_workers; i ++) { worker_threads.push_back (new Worker); addThread (worker_threads.back(), ll_threads); } wakeUpCommunicator (); }
int main(void) { signal(SIGALRM, onalarm); alarm(1); addThread(print1, &main_context2, &main_context1); addThread(print2, &main_context2, &main_context1); getcontext(&main_context1); int turn = 0; while (1) { if (alarmed) { alarmed = 0; turn++; if (turn%time1 == 0) swapcontext(&main_context2, &threads[0]); if (turn%time2 == 0) swapcontext(&main_context2, &threads[1]); } } return 0; }
bool ThreadPool::execute(tasks::Task* task) { boost::unique_lock<Mutex> lock(mutex_); if(shutdown_) return false; if(poolSize_ < minPoolSize_) addThread(); else if(poolSize_ < maxPoolSize_ && (tasks_.size() + activeWorkers_ >= poolSize_)) // add worker addThread(); if(poolSize_ == 0 ) return false; //task push tasks_.emplace(task->priority, task->task); taskCv_.notify_one(); return true; }
void startRunners () { /* Runners */ for (unsigned i = 0; i < the_runners.size (); i ++) if (the_runners [i] -> isAssignedLocally ()) { addThread (the_runners [i], ll_threads); the_runners [i] -> waitStarting (); } printDebugMessage ("launched the parallel runners"); }
/*! Check if there are free threads to handle a new request. If there are not enough threads create a new one. */ void Server::checkThreadsNumber () { threadsMutex->lock (); /* Create a new thread if there are not available threads and we did not reach the limit. */ if ((threads.size () < nMaxThreads) && (freeThreads < 1)) addThread (false); threadsMutex->unlock (); }
void ThreadedSocketAcceptor::onStart() { Sockets::iterator i; for( i = m_sockets.begin(); i != m_sockets.end(); ++i ) { Locker l( m_mutex ); int port = m_socketToPort[*i]; AcceptorThreadInfo* info = new AcceptorThreadInfo( this, *i, port ); thread_id thread; thread_spawn( &socketAcceptorThread, info, thread ); addThread( *i, thread ); } }
int main(void) { struct sigaction sa; struct itimerval timer; memset(&sa, 0, sizeof(sa)); sa.sa_handler = &onalarm; sigaction(SIGALRM, &sa, NULL); timer.it_value.tv_sec = 0; timer.it_value.tv_usec = 25000; setitimer(ITIMER_REAL, &timer, NULL); addThread(print14, &main_context2, &main_context1, 1); addThread(print26, &main_context2, &main_context1, 2); addThread(sumNumbers, &main_context2, &main_context1, 5); getcontext(&main_context1); finishedCnt++; if (finishedCnt <= threadCount) { while (1) { if (alarmed) { alarmed = 0; selectCurrentThread(); } if (threadFinished[currentThread]) selectCurrentThread(); swapcontext(&main_context2, &threads[currentThread]); } } return 0; }
int read_proc(char *buf,char **start,off_t offset,int count,int *eof,void *data ) { char outputBuffer[1001]; int len = 0; struct processInfo* curProcess; struct threadInfo* curThread; if(DEBUG) printk("Entering read_proc\n"); if (offset>0){ return 0; } //Find if current process exists; if not create it curProcess = findProcess(current); // if (DEBUG) curProcess = headProcess; // if (DEBUG) current->pid = headProcess->headThread->pid; if (curProcess==NULL){ if(DEBUG) printk("current process does not exist\n"); curProcess=addProcess(current); curProcess->seed = A_PRNG; if(DEBUG) printk("numThreads:%lu", curProcess->numThreads); }else{ printk("Process already exists. Process not being reseeded"); } //Find if current thread exists; if not create it curThread = findThread(curProcess,current); if (curThread==NULL){ if(DEBUG) printk("creating curret thread\n"); curThread=addThread(curProcess,current); } len = sprintf(outputBuffer, "%ld\n", curThread->nextRandom); if(DEBUG) printk("nextRandom: %lu\n",curThread->nextRandom); curThread->nextRandom = nextRandomGen(curThread->nextRandom, curProcess->numThreads); if (DEBUG) printk("nextnextRandom %lu\n", curThread->nextRandom); if (DEBUG) printk("thread %d\n", curThread->pid); memcpy(buf, outputBuffer, len); /*if()){*/ /*if(DEBUG) printk("copy to user failed\n");*/ /*return -EFAULT; */ /*}*/ *eof = 1; if(DEBUG) printk("Leaving read_proc\n"); return len; }
/// Intercept calls to fork int fork() { // Do the fork int pid = InterposeRoot::fork(); // The child process only has a main thread if(pid == 0) { // No need to lock. There's only one thread in the child process _threads.clear(); addThread(InterposeRoot::pthread_self()); } return pid; }
void ThreadedSocketInitiator::doConnect( const SessionID& s, const Dictionary& d ) { try { Session* session = Session::lookupSession( s ); if( !session->isSessionTime(UtcTimeStamp()) ) return; Log* log = session->getLog(); std::string address; short port = 0; std::string sourceAddress; short sourcePort = 0; getHost( s, d, address, port, sourceAddress, sourcePort ); socket_handle socket = socket_createConnector(); if( m_noDelay ) socket_setsockopt( socket, TCP_NODELAY ); if( m_sendBufSize ) socket_setsockopt( socket, SO_SNDBUF, m_sendBufSize ); if( m_rcvBufSize ) socket_setsockopt( socket, SO_RCVBUF, m_rcvBufSize ); setPending( s ); log->onEvent( "Connecting to " + address + " on port " + IntConvertor::convert((unsigned short)port) + " (Source " + sourceAddress + ":" + IntConvertor::convert((unsigned short)sourcePort) + ")"); ThreadedSocketConnection* pConnection = new ThreadedSocketConnection( s, socket, address, port, getLog(), sourceAddress, sourcePort ); ThreadPair* pair = new ThreadPair( this, pConnection ); { Locker l( m_mutex ); thread_id thread; if ( thread_spawn( &socketThread, pair, thread ) ) { addThread( socket, thread ); } else { delete pair; pConnection->disconnect(); delete pConnection; setDisconnected( s ); } } } catch ( std::exception& ) {} }
/// Initialize the thread tracker Spool() { // Set up a recursive lock pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); // Initialize the lock pthread_mutex_init(&_mutex, &attr); // Destroy the mutex attr pthread_mutexattr_destroy(&attr); // Add the main thread addThread(InterposeRoot::pthread_self()); }
void ThreadPool::workerTerminated(Worker* worker, bool expected) { --poolSize_; --activeWorkers_; if(!expected) { // add new thread, if necessary if(!shutdown_ && poolSize_ < minPoolSize_) addThread(); } WorkerPtr ptr(worker); terminated_.emplace_back(ptr); drainCv_.notify_all(); }
void vHavokCpuJobThreadPool::setNumThreads(int numThreads) { if ( numThreads > MAX_NUM_THREADS ) { numThreads = MAX_NUM_THREADS; } while( m_sharedThreadData.m_numThreads < numThreads ) { addThread(); } while( m_sharedThreadData.m_numThreads > numThreads ) { removeThread(); } }
void initRMC (int & __argc, char * * & __argv) { /* Communication */ initCommunication (); communicator_thread = new Communicator (& __argc, & __argv); addThread (communicator_thread, ll_threads); waitNodeInitialization (); initSending (); /* Scheduler */ if (isScheduleNode ()) { initScheduler (); } }
void *create_bomb(void *arg) { Block *bomb; bomb = (Block *) arg; pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); pthread_mutex_lock(&mutex); addThread(pthread_self()); pthread_mutex_unlock(&mutex); while(bomb->row <= bomb->screen_height) { if(bomb->row == bomb->screen_height - 1) { pthread_mutex_lock(&mutex); if(bomb->col >= bomb->block->start && bomb->col <= bomb->block->end) { increaseScore(); displayScore(); } else { flash(); decreaseScore(score); displayScore(); } delete_bomb(bomb); pthread_mutex_unlock(&mutex); break; } pthread_mutex_lock(&mutex); SET_COLOR_BLUE; move(bomb->row, bomb->col); delch(); insch(' '); (bomb->row)++; SET_COLOR_RED; pthread_mutex_unlock(&mutex); refresh(); pthread_testcancel(); napms(150); } pthread_mutex_lock(&mutex); bomb->cols[bomb->col] = 0; removeThread(pthread_self()); pthread_mutex_unlock(&mutex); free(bomb); pthread_exit((void *) 0); }
T Thread_new(int apply(void *), void *args, int nbytes, ...) { T t; HANDLE hThread; assert(root); assert(apply); assert(args && nbytes >= 0 || args == NULL); if (args == NULL) nbytes = 0; TRY t = ALLOC((sizeof (*t) + nbytes + 15)&~15); memset(t, '\0', sizeof *t); EXCEPT(Mem_Failed) RAISE(Thread_Failed); END_TRY; t->join = CreateSemaphore(NULL, 0, INT_MAX, NULL); if (t->join == NULL) { FREE(t); RAISE(Thread_Failed); } if (nbytes > 0) { t->args = t + 1; memcpy(t->args, args, nbytes); } else t->args = args; t->apply = apply; hThread = (HANDLE)_beginthreadex( NULL, /* default security attributes */ 0, /* default stack size */ start, /* initial function */ t, /* start's argument */ 0, /* default thread creation flags */ &t->IDThread /* where to store the thread id */ ); if (hThread == NULL) { CloseHandle(t->join); FREE(t); RAISE(Thread_Failed); } CloseHandle(hThread); addThread(t); return t; }
int Thread_init(int preempt, ...) { assert(preempt == 0 || preempt == 1); assert(root == NULL); TRY NEW0(root); EXCEPT(Mem_Failed) return -1; END_TRY; join0 = CreateSemaphore(NULL, 0, 1, NULL); if (join0 == NULL) return -1; root->join = CreateSemaphore(NULL, 0, INT_MAX, NULL); if (root->join == NULL) { BOOL result = CloseHandle(join0); assert(result == TRUE); return -1; } InitializeCriticalSection(&csection); root->IDThread = GetCurrentThreadId(); addThread(root); /* handle preempt == 0 */ return 1; }
void ThreadPool::init() { boost::unique_lock<Mutex> lock(mutex_); for(int i = 0; i < minPoolSize_; ++i) addThread(); }
/*! Complete the loading phase. */ int Server::postLoad () { string strCPU; string buffer; /* Get the name of the local machine. */ memset (serverName, 0, HOST_NAME_MAX + 1); Socket::gethostname (serverName, HOST_NAME_MAX); log (MYSERVER_LOG_MSG_INFO, _("Host name: %s"), serverName); /* Find the IP addresses of the local machine. */ try { Socket::getLocalIPsList (ipAddresses); } catch (exception & e) { log (MYSERVER_LOG_MSG_ERROR, _("Error reading IP list")); return -1; } log (MYSERVER_LOG_MSG_INFO, _("IP: %s"), ipAddresses.c_str ()); log (MYSERVER_LOG_MSG_INFO, _("Detected %i CPUs"), (int) getCPUCount ()); connectionsScheduler.restart (); listenThreads.initialize (); getProcessServerManager ()->load (); if (path == NULL) path = new string (); if (getdefaultwd (*path)) return -1; /* Load the home directories configuration. */ homeDir.load (); loadStaticComponents (); loadPlugins (); if (loadVHostConf ()) return -1; /* Load the MIME types. */ log (MYSERVER_LOG_MSG_INFO, _("Loading MIME types from %s..."), mimeConfigurationFile.c_str ()); string handlerStr (getData ("server.mime_handler", "xml")); mimeManager.setDefaultHandler (handlerStr); MimeManagerHandler *mimeHandler = mimeManager.getDefaultHandler (); if (!mimeHandler) { log (MYSERVER_LOG_MSG_ERROR, _("Error creating the MIME types handler: %s"), handlerStr.c_str ()); return -1; } if (int nMIMEtypes = mimeHandler->load (mimeConfigurationFile.c_str ())) log (MYSERVER_LOG_MSG_INFO, _("Using %i MIME types"), nMIMEtypes); else log (MYSERVER_LOG_MSG_ERROR, _("Error while loading MIME types")); for (u_long i = 0; i < nStaticThreads; i++) { log (MYSERVER_LOG_MSG_INFO, _("Creating thread %i..."), (int) (i + 1)); if (addThread (true)) { log (MYSERVER_LOG_MSG_ERROR, _("Error while creating thread")); return -1; } log (MYSERVER_LOG_MSG_INFO, _("Thread %i created"), (int)(i + 1)); } configurationFileManager->close (); delete configurationFileManager; configurationFileManager = NULL; return 0; }
void MainWindow::startThreads() { addThread(QUrl("http://www.hhh.de/")); }
void eProfiler::addThisThread(const eString &name) { addThread(eThread::getThisContext(), name); }
IoWorkThread* IOCompletionPort::addDefaultThread() { return addThread( (IoWorkThread*)NULL ); }
long XDbgProxy::run() { MyTrace("XDBG Thread started"); DWORD sleepTime = 0; while (!_stopFlag) { if (_attached) { { // MutexGuard guard(this); DebugEventPacket event; DebugAckPacket ack; if (popDbgEvent(event)) { MyTrace("%s(): eventId: %d, threadId: %d", __FUNCTION__, event.event.dwDebugEventCode, event.event.dwThreadId); switch (event.event.dwDebugEventCode) { case EXCEPTION_DEBUG_EVENT: _exceptHandleCode = AsyncVectoredHandler(event); break; case LOAD_DLL_DEBUG_EVENT: if (!sendDbgEvent(event, ack)) { break; } if (event.event.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT) { free(event.event.u.LoadDll.lpImageName); } break; case UNLOAD_DLL_DEBUG_EVENT: if (!sendDbgEvent(event, ack)) { break; } break; case CREATE_THREAD_DEBUG_EVENT: if (threadIdToHandle(event.event.dwThreadId) != NULL) { // reentry break; } if (!sendDbgEvent(event, ack)) { break; } addThread(event.event.dwThreadId); break; case EXIT_THREAD_DEBUG_EVENT: if (threadIdToHandle(event.event.dwThreadId) == NULL) { // reentry break;; } if (!sendDbgEvent(event, ack)) { break; } delThread(event.event.dwThreadId); break; default: break; } SetEvent(_evtQueueEvent); sleepTime = 0; } else { Sleep(sleepTime); sleepTime ++; if (sleepTime > 15) { sleepTime = 15; if (!PeekNamedPipe(_hPipe, NULL, 0, NULL, 0, NULL)) { _attached = false; CloseHandle(_hPipe); _hPipe = INVALID_HANDLE_VALUE; } } } } } else { if (!createEventPipe()) { continue; } if (!ConnectNamedPipe(_hPipe, NULL)) { if (GetLastError() == ERROR_PIPE_CONNECTED) { onDbgConnect(); _attached = true; MyTrace("debugger attached"); continue; } else { MyTrace("%s(): ConnectNamedPipe(%p) failed. errCode: %d ", __FUNCTION__, _hPipe, GetLastError()); // assert(false); // return -1; CloseHandle(_hPipe); _hPipe = INVALID_HANDLE_VALUE; Sleep(100); } } else { onDbgConnect(); _attached = true; MyTrace("debugger attached"); } } } return 0; }
int write_proc(struct file *file,const char *buf,int count,void *data ) { char bufCopy[1001]; long seed = 0; /*int numThreads = 0;*/ /*int len = 0;*/ struct processInfo* curProcess; struct threadInfo* curThread; struct task_struct* taskNext; //Nothing to write if (count==0){ return 0; } //Set upper limit on size if(count > MAX_PROC_SIZE) count = MAX_PROC_SIZE; //Copy from user to kernal space if(copy_from_user(bufCopy,buf, count)) return -EFAULT; //Set terminating character /*bufCopy[count] = '\0';*/ //Pull out numbers from user sscanf(bufCopy, "%lu",&seed); //If no seed chosen if (seed==0){ seed = A_PRNG; } printk("proccess id: %d", current->tgid); //Find if current process exists; if not create it curProcess = findProcess(current); if (curProcess==NULL){ curProcess=addProcess(current); curProcess->seed = seed; }else{ printk("Process already exists. Process not being reseeded."); curProcess->numThreads++; printk("threads:%d\n", curProcess->numThreads); /* taskNext = next_task(current); while (taskNext&&taskNext->pid!=current->pid){ curProcess->numThreads++; printk("threads:\n",curProcess->numThreads ); taskNext = next_task(taskNext); }*/ } //Find if current thread exists; if not create it curThread = findThread(curProcess,current); if (curThread==NULL){ curThread=addThread(curProcess,current); } if(DEBUG) printk("Exiting write proc\n"); memcpy(proc_data,bufCopy,count); if(DEBUG) printk("Exiting write_proc seed:%lu s\n",seed); return count; }
FixedThreadPool(uint32_t threadsCount) { for (uint32_t i = 0; i < threadsCount; i++) { addThread(); } }
/** * @param val the current pgd-cr3 value * * The task list can be obtained in two ways. * 1. Using next_task_struct which uses the global symbol for init_task as the starting point * 2. Using the current_task_struct structure. This should just "work" although there are some * special considerations in some special cases. current_task_struct returns the actual * task struct - which can either be a process task struct or a thread task struct (if it * is single threaded). Either way, it is guaranteed that the next pointer in task struct * will either point to the next process task struct or init_task. Which means the loop * should still work. * * Perhaps it is helpful to illustrate how the process/thread list really works * There are two fields in the task_struct that are of interest * 1. The next pointer that points to the next task struct * 2. The thread_group field (which is of type struct list_head { list_head* next, prev }) * This means task_struct.thred_group will automatically give you next. The tricky thing * is that this list points to the thread_group field of the next task_struct that belongs * to this group. See the figure below. * To put things together, lets assume that we have two running processes, 30 and 31. * 31 is single threaded and 30 is multi-threaded with two additional threads 32 and 33. * Given that we always have init_task, we should have a total of 5 task_structs, 1 for init * 2 for the processes and 2 for the threads. * The following is a graphical representation of the "process list" * * ,--------------------------------------------------------------------, * | _____________ _____________ _____________ | * |---> | pid = 0 | ,---> | pid = 30 | ,---> | pid = 31 | | * | | tgid = 0 | | | tgid = 30 | | | tgid = 31 | | * | | next | ---' | next | ---| | next | ---' * | ,-> | t-group | -, ,-> | t-group | -, | ,-> | t-group | --, * | | |___________| | / |___________| | | | |___________| | * | '------------------' / | | '-------------------' * | / ,-------------------' | * | | | _____________ | * | | | | pid = 32 | | * | | | | tgid = 30 | | * | | | | next | ---' (points to real next) * | | '--> | t-group | --, * | | |___________| | * | | ,--------------------' * | | | _____________ * | | | | pid = 33 | * | | | | tgid = 30 | * | | | | next | ----, (points to init_task) * | | '--> | t-group | --, | * | | |___________| | | * | '-----------------------' | * '----------------------------------------------' * * Some things to emphasize (again?) * 1. thread_group.next (represented by t-group) points to the next thread_group field! * 2. next of the process task struct in the process list is guaranteed to point to the next * task struct. The next in the thread task_struct might point to next or init_task * 3. According to online references, the pid's are always unique - this is why thread ids * for the process 30 are 30 (the main thread) 32 and 33 (the other two threads). * 4. The tgid shows the real pid. * * The above example does not include the "thread_info" structure. Each task_struct * is associated with its own thread_info structure which is pointed to by the "stack" field of the * task_struct. To DECAF_get the stack address of the task - we will have to go into the thread info structure * and look at the cpu_context field to grab the stack pointer. More info on the cpu_context and copy_thread * (called from copy_process called from do_fork) can be found in arch/ARCH/kernel/process.c */ gva_t updateProcessListByTask(CPUState* env, gva_t task, int updateMask, int bNeedMark) { DECAF_Processes_Callback_Params params; gpid_t pid; gpid_t parentPid; gpid_t tgid; gpid_t glpid; target_ulong uid; target_ulong gid; target_ulong euid; target_ulong egid; gpid_t t_pid; gpid_t t_tgid; gpa_t pgd; char name[MAX_PROCESS_INFO_NAME_LEN]; char argName[MAX_PROCESS_INFO_NAME_LEN]; gva_t i = task; argName[0] = '\0'; name[0] = '\0'; pid = DECAF_get_pid(env, i); tgid = DECAF_get_tgid(env, i); glpid = DECAF_get_group_leader_pid(env, i); uid = DECAF_get_uid(env, i); gid = DECAF_get_gid(env, i); euid = DECAF_get_euid(env, i); egid = DECAF_get_egid(env, i); parentPid = DECAF_get_parent_pid(env, i); pgd = pgd_strip(DECAF_get_pgd(env, i)); int ret = 0; if (curProcessPGD == pgd) { if (DECAF_get_arg_name(env, i, argName, MAX_PROCESS_INFO_NAME_LEN) < 0) { argName[0] = '\0'; } } if (DECAF_get_name(env, i, name, MAX_PROCESS_INFO_NAME_LEN) < 0) //get the name { name[0] = '\0'; } //update the info if needed if ( ((bNeedMark) && (processMark(pid) == 1)) || ((!bNeedMark) && (findProcessByPID(pid) == NULL)) ) // i.e. it doesn't exist { addProcess(i, pid, parentPid, tgid, glpid, uid, gid, euid, egid, pgd, (argName[0] == '\0') ? NULL : argName, (name[0] == '\0') ? NULL : name); processMark(pid); params.cp.pid = pid; params.cp.pgd = pgd; SimpleCallback_dispatch(&DroidScope_callbacks[DECAF_PROCESSES_CREATE_PROCESS_CB], ¶ms); //force a module and thread update updateMask |= UPDATE_THREADS | UPDATE_MODULES; } else { ret = updateProcess(i, pid, parentPid, tgid, glpid, uid, gid, euid, egid, pgd, (argName[0] == '\0') ? NULL : argName, (name[0] == '\0') ? NULL : name); if (ret > 0) { params.pu.pid = pid; params.pu.mask = ret; SimpleCallback_dispatch(&DroidScope_callbacks[DECAF_PROCESSES_PROCESS_UPDATED_CB], ¶ms); } } if (updateMask & UPDATE_THREADS) { //update (repopulate) the threads gva_t j = i; clearThreads(pid); do { if ((j != 0) && (j != -1)) { t_pid = DECAF_get_pid(env, j); t_tgid = DECAF_get_tgid(env, j); //run through the thread group gva_t parentTI = DECAF_get_stack(env, j); addThread(t_tgid, t_pid, parentTI); } j = DECAF_get_thread_group(env, j); if ( (j == -1) || (j == 0) ) { break; } j -= task_struct_thread_group_offset;//this gives you the next one immediately } while ( i != j ); } //end bUpdateThreads //update (repopulate) the module list if (updateMask & UPDATE_MODULES) { updateProcessModuleList(env, pid); } i = DECAF_get_next_task_struct(env, i); return (i); }
void ThreadedSSLSocketInitiator::doConnect(const SessionID &s, const Dictionary &d) { try { Session *session = Session::lookupSession(s); if (!session->isSessionTime(UtcTimeStamp())) return; Log *log = session->getLog(); std::string address; short port = 0; getHost(s, d, address, port); int socket = socket_createConnector(); if (m_noDelay) socket_setsockopt(socket, TCP_NODELAY); if (m_sendBufSize) socket_setsockopt(socket, SO_SNDBUF, m_sendBufSize); if (m_rcvBufSize) socket_setsockopt(socket, SO_RCVBUF, m_rcvBufSize); setPending(s); log->onEvent("Connecting to " + address + " on port " + IntConvertor::convert((unsigned short)port)); SSL *ssl = SSL_new(m_ctx); if (ssl == 0) { log->onEvent("Failed to create ssl object"); return; } SSL_clear(ssl); BIO *sbio = BIO_new_socket(socket, BIO_CLOSE); SSL_set_bio(ssl, sbio, sbio); ThreadedSSLSocketConnection *pConnection = new ThreadedSSLSocketConnection( s, socket, ssl, address, port, getLog()); ThreadPair *pair = new ThreadPair(this, pConnection); { Locker l(m_mutex); thread_id thread; if (thread_spawn(&socketThread, pair, thread)) { addThread(SocketKey(socket, ssl), thread); } else { delete pair; pConnection->disconnect(); delete pConnection; SSL_free(ssl); setDisconnected(s); } } } catch (std::exception &) { } }