summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/modules/extra/m_mysql.cpp53
1 files changed, 46 insertions, 7 deletions
diff --git a/src/modules/extra/m_mysql.cpp b/src/modules/extra/m_mysql.cpp
index fc804d50e..862dde811 100644
--- a/src/modules/extra/m_mysql.cpp
+++ b/src/modules/extra/m_mysql.cpp
@@ -576,6 +576,30 @@ void LoadDatabases(ConfigReader* conf, InspIRCd* ServerInstance)
ConnectDatabases(ServerInstance);
}
+char FindCharId(const std::string &id)
+{
+ char i = 1;
+ for (ConnMap::iterator iter = Connections.begin(); iter != Connections.end(); ++iter, ++i)
+ {
+ if (iter->first == id)
+ {
+ return i;
+ }
+ }
+ return 0;
+}
+
+ConnMap::iterator GetCharId(char id)
+{
+ char i = 1;
+ for (ConnMap::iterator iter = Connections.begin(); iter != Connections.end(); ++iter, ++i)
+ {
+ if (i == id)
+ return iter;
+ }
+ return Connections.end();
+}
+
void NotifyMainThread(SQLConnection* connection_with_new_result)
{
/* Here we write() to the socket the main thread has open
@@ -586,8 +610,16 @@ void NotifyMainThread(SQLConnection* connection_with_new_result)
* thread, we can just use standard connect(), and we can
* block if we like. We just send the connection id of the
* connection back.
+ *
+ * NOTE: We only send a single char down the connection, this
+ * way we know it wont get a partial read at the other end if
+ * the system is especially congested (see bug #263).
+ * The function FindCharId translates a connection name into a
+ * one character id, and GetCharId translates a character id
+ * back into an iterator.
*/
- send(QueueFD, connection_with_new_result->GetID().c_str(), connection_with_new_result->GetID().length()+1, 0);
+ char id = FindCharId(connection_with_new_result->GetID());
+ send(QueueFD, &id, 1, 0);
}
void* DispatcherThread(void* arg);
@@ -639,13 +671,17 @@ class Notifier : public InspSocket
virtual bool OnDataReady()
{
- char* data = this->Read();
- ConnMap::iterator iter;
-
- if (data && *data)
+ char data = 0;
+ /* NOTE: Only a single character is read so we know we
+ * cant get a partial read. (We've been told that theres
+ * data waiting, so we wont ever get EAGAIN)
+ * The function GetCharId translates a single character
+ * back into an iterator.
+ */
+ if (read(this->GetFd(), &data, 1) > 0)
{
- /* We expect to be sent a null terminated string */
- if((iter = Connections.find(data)) != Connections.end())
+ ConnMap::iterator iter = GetCharId(data);
+ if (iter != Connections.end())
{
/* Lock the mutex, send back the data */
pthread_mutex_lock(&results_mutex);
@@ -655,8 +691,11 @@ class Notifier : public InspSocket
pthread_mutex_unlock(&results_mutex);
return true;
}
+ /* No error, but unknown id */
+ return true;
}
+ /* Erk, error on descriptor! */
return false;
}
};