Hi all
For those who are using my throttling EMI patch posted a few month ago on
this ML
Here is an rare issue that can make the sending thread waiting for lifetime.
The issue is reproductible when no MT is sent for a while so
'last_mt_microtime' is not initialized.
We fix it at connect (UCP 60), we will now initialize this variable to the
current microtime.
2007-03-23 11:05:30.450 [12348] [53] DEBUG: EMI2[SMSC_8]: QOS: Throughput
detected, we need to sleep <1.000000>sec
2007-03-23 11:05:31.450 [12348] [53] DEBUG: EMI2[SMSC_8]: QOS: Sleeping
Done.
2007-03-23 11:05:31.450 [12348] [53] DEBUG: EMI2[SMSC_8]: QOS:
last_mt_microtime:<3689911777816892928.000000> now:<1174644331.450592>
delay:<1.000000>
2007-03-23 11:05:31.450 [12348] [53] DEBUG: EMI2[SMSC_8]: QOS: Traffic
Policy exceeded, we need to sleep <3689911776642248704.000000>sec
2007-03-23 12:30:41.659 [12348] [53] DEBUG: EMI2[SMSC_8]: QOS: Traffic
Policy exceeded, we need to sleep <3689911776642243584.000000>sec
2007-03-23 12:30:52.730 [12348] [53] DEBUG: EMI2[SMSC_8]: QOS: Traffic
Policy exceeded, we need to sleep <3689911776642243584.000000>sec
2007-03-23 12:30:55.739 [12348] [53] DEBUG: EMI2[SMSC_8]: QOS: Traffic
Policy exceeded, we need to sleep <3689911776642243584.000000>sec
2007-03-23 12:30:57.244 [12348] [53] DEBUG: EMI2[SMSC_8]: QOS: Traffic
Policy exceeded, we need to sleep <3689911776642243584.000000>sec
2007-03-23 12:30:59.261 [12348] [53] DEBUG: EMI2[SMSC_8]: QOS: Traffic
Policy exceeded, we need to sleep <3689911776642243584.000000>sec
Vincent.
--
Telemaque - 06560 SOPHIA-ANTIPOLIS - (FR)
Service Technique/Reseau - NOC
Developpement SMS/MMS/Kiosques
http://www.telemaque.fr/
[EMAIL PROTECTED]
--- /gateway-cvs/gw/smsc/smsc_emi.c 2006-04-07 14:54:06.000000000 +0200
+++ /gateway/gw/smsc/smsc_emi.c 2006-06-14 18:29:06.000000000 +0200
@@ -122,6 +122,7 @@
int priv_nexttrn; /* next TRN, this should never be accessed
directly.
* use int emi2_next_trn (SMSCConn *conn)
instead.
*/
+ struct timeval last_mt_microtime; /* the last microtime a MT was sent
over the SMSC */
time_t last_activity_time; /* the last time something was sent over the
main
* SMSC connection
*/
@@ -168,6 +169,9 @@
if (result >= 0 && emimsg->or == 'O' && ( emimsg->ot == 31 || emimsg->ot ==
51)) {
PRIVDATA(conn)->last_activity_time = time (NULL);
+ if (emimsg->ot == 51) {
+ gettimeofday(&PRIVDATA(conn)->last_mt_microtime, 0);
+ }
}
return result;
@@ -260,6 +264,9 @@
emimsg->fields[E60_PWD] = octstr_duplicate(privdata->password);
octstr_binary_to_hex(emimsg->fields[E60_PWD], 1);
emimsg->fields[E60_VERS] = octstr_create("0100");
+
+ /* initializing time for QOS */
+ gettimeofday(&privdata->last_mt_microtime, 0);
return emimsg;
}
@@ -988,9 +990,13 @@
*/
static int emi2_do_send(SMSCConn *conn, Connection *server)
{
+ PrivData *privdata = conn->data;
struct emimsg *emimsg;
+ struct timeval tv;
Msg *msg;
double delay = 0;
+ double mt_microtime = 0;
+ double microtime = 0;
if (conn->throughput > 0) {
delay = 1.0 / conn->throughput;
@@ -1002,7 +1008,35 @@
int nexttrn = emi2_next_trn(conn);
if (conn->throughput > 0)
- gwthread_sleep(delay);
+ {
+ debug("smsc.emi2", 0, "EMI2[%s]: QOS: Throughput detected, we need to sleep
<%f>sec", octstr_get_cstr(conn->id), delay);
+
+ gwthread_sleep(delay); /* Sleeping */
+
+ debug("smsc.emi2", 0, "EMI2[%s]: QOS: Sleeping Done.",
octstr_get_cstr(conn->id));
+
+ gettimeofday(&tv, 0); /* Refreshing time */
+
+ mt_microtime = PRIVDATA(conn)->last_mt_microtime.tv_sec
+ + (double) PRIVDATA(conn)->last_mt_microtime.tv_usec / 1000000;
+ microtime = tv.tv_sec + (double) tv.tv_usec / 1000000;
+
+ debug("smsc.emi2", 0, "EMI2[%s]: QOS: last_mt_microtime:<%f> now:<%f>
delay:<%f>",
+ octstr_get_cstr(conn->id), mt_microtime, microtime, delay);
+
+ while (mt_microtime + delay > microtime)
+ {
+ debug("smsc.emi2", 0, "EMI2[%s]: QOS: Traffic Policy exceeded, we need to
sleep <%f>sec",
+ octstr_get_cstr(conn->id), (mt_microtime + delay) -
microtime);
+ /* Sleeping rest of time */
+ gwthread_sleep((mt_microtime + delay) - microtime);
+
+ gettimeofday(&tv, 0); /* Refreshing time */
+
+ mt_microtime = PRIVDATA(conn)->last_mt_microtime.tv_sec +
(double) PRIVDATA(conn)->last_mt_microtime.tv_usec / 1000000;
+ microtime = tv.tv_sec + (double) tv.tv_usec / 1000000;
+ }
+ }