Beispiel #1
0
bool TimerManager::EnableTimer(uint64_t id) {
    assert(!IsStoped());

    MutexLocker locker(&m_mutex);
    TimerEntry* entry = FindEntry(id);
    if (entry) {
        entry->is_enabled = true;
        SetNextTimeout(id, entry->interval, entry->revision);
        return true;
    }
    return false;
}
Beispiel #2
0
void POP3SetTimeout(eNextState NextTCPState, pop3aggr *pMsg)
{
	AsyncIO *IO = &pMsg->IO;
	double Timeout = 0.0;

	EVP3C_syslog(LOG_DEBUG, "POP3: %s\n", __FUNCTION__);

	switch (NextTCPState) {
	case eSendFile:
	case eSendReply:
	case eSendMore:
		Timeout = POP3_C_SendTimeouts[pMsg->State];
/*
  if (pMsg->State == eDATABody) {
  / * if we're sending a huge message, we need more time. * /
  Timeout += StrLength(pMsg->msgtext) / 1024;
  }
*/
		break;
	case eReadFile:
	case eReadMessage:
		Timeout = POP3_C_ReadTimeouts[pMsg->State];
/*
  if (pMsg->State == eDATATerminateBody) {
  / *
  * some mailservers take a nap before accepting the message
  * content inspection and such.
  * /
  Timeout += StrLength(pMsg->msgtext) / 1024;
  }
*/
		break;
	case eReadPayload:
		Timeout = 100000;
		/* TODO!!! */
		break;
	case eSendDNSQuery:
	case eReadDNSReply:
	case eConnect:
	case eTerminateConnection:
	case eDBQuery:
	case eAbort:
	case eReadMore://// TODO
		return;
	}
	SetNextTimeout(&pMsg->IO, Timeout);
}
Beispiel #3
0
uint64_t TimerManager::AddTimer(int64_t interval, bool is_period,
                                CallbackClosure* closure) {
    assert(interval >= 0);
    assert(!IsStoped());

    MutexLocker locker(&m_mutex);
    uint64_t id = NewTimerId();
    TimerEntry& timer = m_timers[id];
    timer.interval = interval;
    timer.is_period = is_period;
    timer.closure = closure;
    timer.is_enabled = true;

    SetNextTimeout(id, interval, 0);

    return id;
}
void SMTPSetTimeout(eNextState NextTCPState, SmtpOutMsg *Msg)
{
	double Timeout = 0.0;
	AsyncIO *IO = &Msg->IO;

	EVS_syslog(LOG_DEBUG, "%s\n", __FUNCTION__);

	switch (NextTCPState) {
	case eSendFile:
	case eSendReply:
	case eSendMore:
		Timeout = SMTP_C_SendTimeouts[Msg->State];
		if (Msg->State == eDATABody) {
			/* if we're sending a huge message,
			 * we need more time.
			 */
			Timeout += StrLength(Msg->msgtext) / 512;
		}
		break;
	case eReadMessage:
		Timeout = SMTP_C_ReadTimeouts[Msg->State];
		if (Msg->State == eDATATerminateBody) {
			/*
			 * some mailservers take a nap before accepting
			 * the message content inspection and such.
			 */
			Timeout += StrLength(Msg->msgtext) / 512;
		}
		break;
	case eSendDNSQuery:
	case eReadDNSReply:
	case eDBQuery:
	case eReadFile:
	case eReadMore:
	case eReadPayload:
	case eConnect:
	case eTerminateConnection:
	case eAbort:
		return;
	}
	SetNextTimeout(&Msg->IO, Timeout);
}
Beispiel #5
0
bool TimerManager::ModifyTimer(uint64_t id, int64_t interval,
                               CallbackClosure* closure) {
    assert(!IsStoped());

    MutexLocker locker(&m_mutex);
    TimerEntry* entry = FindEntry(id);
    if (entry) {
        entry->interval = interval;
        if (entry->closure != closure) {
            delete entry->closure; // release the old closure
            entry->closure = closure;
        }
        entry->revision++;
        if (entry->is_enabled) {
            SetNextTimeout(id, interval, entry->revision);
        }
        return true;
    }
    return false;
}
Beispiel #6
0
/* virtual */ OP_BOOLEAN
ES_TimeoutTimerEvent::Expire()
{
	ES_Context *context = runtime->CreateContext(NULL);
	if (!context)
		return OpStatus::ERR_NO_MEMORY;

	ES_TimeoutThread *thread = OP_NEW(ES_TimeoutThread, (context, shared));
	if (!thread)
	{
		ES_Runtime::DeleteContext(context);
		return OpStatus::ERR_NO_MEMORY;
	}

	thread->SetOriginInfo(origin_info);
	thread->SetTimerEvent(this);
#ifdef SCOPE_PROFILER
	thread->SetThreadId(GetScopeThreadId());
#endif // SCOPE_PROFILER

	if (from_plugin_origin)
		thread->SetIsPluginThread();

	OP_BOOLEAN stat = runtime->GetESScheduler()->AddRunnable(thread);
	if (stat == OpBoolean::IS_TRUE)
		/* Thread added to scheduler. Add listener after AddRunnable() since it
		   deletes the thread and all its listeners if scheduler is draining. */
		thread->AddListener(this);
	else if (stat == OpBoolean::IS_FALSE)
		/* Thread not added. Make it repeat here. */
		if (IsRepeating())
		{
			SetNextTimeout();
			SetPreviousDelay(GetTotalRequestedDelay());
			if (OpStatus::IsMemoryError(GetTimerManager()->RepeatEvent(this)))
				return OpBoolean::ERR_NO_MEMORY;
			return OpBoolean::IS_TRUE;
		}

	return stat;
}
Beispiel #7
0
void TimerManager::Dispatch() {
    uint64_t id;

    // Make a copy. It's necessary because the entry in the map maybe changed
    // by it's closure.
    TimerEntry entry;

    while (DequeueTimeoutEntry(&id, &entry)) {
        // Run the closure in unlocked state
        if (entry.closure != NULL) {
            entry.closure->Run(id);
        }

        MutexLocker locker(&m_mutex);
        m_running_timer = 0;
        if (entry.is_period) {
            TimerMap::iterator it = m_timers.find(id);
            if (it != m_timers.end()) {
                // restore the closure if necessory
                if (entry.closure != NULL) {
                    if (it->second.closure == NULL) {
                        it->second.closure = entry.closure;
                    } else {
                        // the entry in the map has been assign a new one,
                        // release the old closure;
                        delete entry.closure;
                    }
                }
                if (it->second.is_enabled) {
                    SetNextTimeout(it->first, it->second.interval,
                                   it->second.revision);
                }
            } else {
                // the timer has been removed
                delete entry.closure;
            }
        }
    }
}
Beispiel #8
0
static void
IO_recv_callback(struct ev_loop *loop, ev_io *watcher, int revents)
{
	const char *errmsg;
	ssize_t nbytes;
	AsyncIO *IO = watcher->data;

	SET_EV_TIME(IO, event_base);
	switch (IO->NextState) {
	case eReadFile:
		nbytes = FileRecvChunked(&IO->IOB, &errmsg);
		if (nbytes < 0)
			StrBufPlain(IO->ErrMsg, errmsg, -1);
		else
		{
			if (IO->IOB.ChunkSendRemain == 0)
			{
				IO->NextState = eSendReply;
				assert(IO->ReadDone);
				ev_io_stop(event_base, &IO->recv_event);
				PostInbound(IO);
				return;
			}
			else
				return;
		}
		break;
	default:
		nbytes = StrBuf_read_one_chunk_callback(IO->RecvBuf.fd,
							0,
							&IO->RecvBuf);
		break;
	}

#ifdef BIGBAD_IODBG
	{
		long nbytes;
		int rv = 0;
		char fn [SIZ];
		FILE *fd;
		const char *pch = ChrPtr(IO->RecvBuf.Buf);
		const char *pchh = IO->RecvBuf.ReadWritePointer;

		if (pchh == NULL)
			pchh = pch;

		nbytes = StrLength(IO->RecvBuf.Buf) - (pchh - pch);
		snprintf(fn, SIZ, "/tmp/foolog_ev_%s.%d",
			 ((CitContext*)(IO->CitContext))->ServiceName,
			 IO->SendBuf.fd);

		fd = fopen(fn, "a+");
		if (fd == NULL) {
			syslog(LOG_EMERG, "failed to open file %s: %s", fn, strerror(errno));
			cit_backtrace();
			exit(1);
		}
		fprintf(fd, "Read: BufSize: %ld BufContent: [",
			nbytes);
		rv = fwrite(pchh, nbytes, 1, fd);
		if (!rv) printf("failed to write debug to %s!\n", fn);
		fprintf(fd, "]\n");
		fclose(fd);
	}
#endif
	if (nbytes > 0) {
		HandleInbound(IO);
	} else if (nbytes == 0) {
		StopClientWatchers(IO, 1);
		SetNextTimeout(IO, 0.01);
		return;
	} else if (nbytes == -1) {
		if (errno != EAGAIN) {
			// FD is gone. kick it. 
			StopClientWatchers(IO, 1);
			EV_syslog(LOG_DEBUG,
				  "IO_recv_callback(): Socket Invalid! [%d] [%s] [%d]\n",
				  errno, strerror(errno), IO->SendBuf.fd);
			StrBufPrintf(IO->ErrMsg,
				     "Socket Invalid! [%s]",
				     strerror(errno));
			SetNextTimeout(IO, 0.01);
		}
		return;
	}
}
Beispiel #9
0
static void
IO_send_callback(struct ev_loop *loop, ev_io *watcher, int revents)
{
	int rc;
	AsyncIO *IO = watcher->data;
	const char *errmsg = NULL;

	SET_EV_TIME(IO, event_base);
	become_session(IO->CitContext);
#ifdef BIGBAD_IODBG
	{
		int rv = 0;
		char fn [SIZ];
		FILE *fd;
		const char *pch = ChrPtr(IO->SendBuf.Buf);
		const char *pchh = IO->SendBuf.ReadWritePointer;
		long nbytes;

		if (pchh == NULL)
			pchh = pch;

		nbytes = StrLength(IO->SendBuf.Buf) - (pchh - pch);
		snprintf(fn, SIZ, "/tmp/foolog_ev_%s.%d",
			 ((CitContext*)(IO->CitContext))->ServiceName,
			 IO->SendBuf.fd);

		fd = fopen(fn, "a+");
		if (fd == NULL) {
			syslog(LOG_EMERG, "failed to open file %s: %s", fn, strerror(errno));
			cit_backtrace();
			exit(1);
		}
		fprintf(fd, "Send: BufSize: %ld BufContent: [",
			nbytes);
		rv = fwrite(pchh, nbytes, 1, fd);
		if (!rv) printf("failed to write debug to %s!\n", fn);
		fprintf(fd, "]\n");
#endif
		switch (IO->NextState) {
		case eSendFile:
			rc = FileSendChunked(&IO->IOB, &errmsg);
			if (rc < 0)
				StrBufPlain(IO->ErrMsg, errmsg, -1);
			break;
		default:
			rc = StrBuf_write_one_chunk_callback(IO->SendBuf.fd,
							     0,
							     &IO->SendBuf);
		}

#ifdef BIGBAD_IODBG
		fprintf(fd, "Sent: BufSize: %d bytes.\n", rc);
		fclose(fd);
	}
#endif
	if (rc == 0)
	{
		ev_io_stop(event_base, &IO->send_event);
		switch (IO->NextState) {
		case eSendMore:
			assert(IO->SendDone);
			IO->NextState = IO->SendDone(IO);

			if ((IO->NextState == eTerminateConnection) ||
			    (IO->NextState == eAbort) )
				ShutDownCLient(IO);
			else {
				ev_io_start(event_base, &IO->send_event);
			}
			break;
		case eSendFile:
			if (IO->IOB.ChunkSendRemain > 0) {
				ev_io_start(event_base, &IO->recv_event);
				SetNextTimeout(IO, 100.0);

			} else {
				assert(IO->ReadDone);
				IO->NextState = IO->ReadDone(IO);
				switch(IO->NextState) {
				case eSendDNSQuery:
				case eReadDNSReply:
				case eDBQuery:
				case eConnect:
					break;
				case eSendReply:
				case eSendMore:
				case eSendFile:
					ev_io_start(event_base,
						    &IO->send_event);
					break;
				case eReadMessage:
				case eReadMore:
				case eReadPayload:
				case eReadFile:
					break;
				case eTerminateConnection:
				case eAbort:
					break;
				}
			}
			break;
		case eSendReply:
		    if (StrBufCheckBuffer(&IO->SendBuf) != eReadSuccess)
			break;
		    IO->NextState = eReadMore;
		case eReadMore:
		case eReadMessage:
		case eReadPayload:
		case eReadFile:
			if (StrBufCheckBuffer(&IO->RecvBuf) == eBufferNotEmpty)
			{
				HandleInbound(IO);
			}
			else {
				ev_io_start(event_base, &IO->recv_event);
			}

			break;
		case eDBQuery:
			/*
			 * we now live in another queue,
			 * so we have to unregister.
			 */
			ev_cleanup_stop(loop, &IO->abort_by_shutdown);
			break;
		case eSendDNSQuery:
		case eReadDNSReply:
		case eConnect:
		case eTerminateConnection:
		case eAbort:
			break;
		}
	}
	else if (rc < 0) {
		if (errno != EAGAIN) {
			StopClientWatchers(IO, 1);
			EV_syslog(LOG_DEBUG,
				  "IO_send_callback(): Socket Invalid! [%d] [%s] [%d]\n",
				  errno, strerror(errno), IO->SendBuf.fd);
			StrBufPrintf(IO->ErrMsg,
				     "Socket Invalid! [%s]",
				     strerror(errno));
			SetNextTimeout(IO, 0.01);
		}
	}
	/* else : must write more. */
}