218c6c9d0d
git-svn-id: http://svn.sabayonlinux.org/overlay@2037 d7aec97c-591d-0410-af39-a8856400b30a
358 lines
9.8 KiB
Diff
358 lines
9.8 KiB
Diff
Index: src/rpc.c
|
|
===================================================================
|
|
--- src/rpc.c (révision 460)
|
|
+++ src/rpc.c (révision 466)
|
|
@@ -29,6 +29,7 @@
|
|
|
|
#include "sysdeps.h"
|
|
|
|
+#include <assert.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <stdarg.h>
|
|
@@ -288,6 +289,7 @@
|
|
// Client / Server connection
|
|
struct rpc_connection_t {
|
|
int type;
|
|
+ int status;
|
|
int socket;
|
|
char *socket_path;
|
|
int server_socket;
|
|
@@ -299,6 +301,47 @@
|
|
char send_buffer[BUFSIZ];
|
|
};
|
|
|
|
+// Returns connection status
|
|
+static inline int _rpc_status(rpc_connection_t *connection)
|
|
+{
|
|
+ return connection->status;
|
|
+}
|
|
+
|
|
+int rpc_status(rpc_connection_t *connection)
|
|
+{
|
|
+ if (connection == NULL)
|
|
+ return RPC_STATUS_BROKEN;
|
|
+ return _rpc_status(connection);
|
|
+}
|
|
+
|
|
+// Set connection status
|
|
+static void _rpc_set_status(rpc_connection_t *connection, int error)
|
|
+{
|
|
+ if (connection->status == RPC_STATUS_ACTIVE) {
|
|
+ switch (error) {
|
|
+ case RPC_ERROR_NO_ERROR:
|
|
+ connection->status = RPC_STATUS_ACTIVE;
|
|
+ break;
|
|
+ case RPC_ERROR_CONNECTION_CLOSED:
|
|
+ connection->status = RPC_STATUS_CLOSED;
|
|
+ break;
|
|
+ default:
|
|
+ connection->status = RPC_STATUS_BROKEN;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+static inline int rpc_error(rpc_connection_t *connection, int error)
|
|
+{
|
|
+ // XXX: this function must be called only in case of error
|
|
+ // (otherwise, it's an internal error)
|
|
+ assert(error < 0);
|
|
+ assert(connection != NULL);
|
|
+ _rpc_set_status(connection, error);
|
|
+ return error;
|
|
+}
|
|
+
|
|
// Returns socket fd or -1 if invalid connection
|
|
int rpc_socket(rpc_connection_t *connection)
|
|
{
|
|
@@ -374,6 +417,7 @@
|
|
if (connection == NULL)
|
|
return NULL;
|
|
connection->type = RPC_CONNECTION_SERVER;
|
|
+ connection->status = RPC_STATUS_CLOSED;
|
|
connection->socket = -1;
|
|
connection->server_thread_active = 0;
|
|
connection->callbacks = NULL;
|
|
@@ -404,6 +448,7 @@
|
|
return NULL;
|
|
}
|
|
|
|
+ connection->status = RPC_STATUS_ACTIVE;
|
|
return connection;
|
|
}
|
|
|
|
@@ -423,6 +468,7 @@
|
|
if (connection == NULL)
|
|
return NULL;
|
|
connection->type = RPC_CONNECTION_CLIENT;
|
|
+ connection->status = RPC_STATUS_CLOSED;
|
|
connection->server_socket = -1;
|
|
connection->callbacks = NULL;
|
|
connection->n_callbacks = 0;
|
|
@@ -467,6 +513,7 @@
|
|
return NULL;
|
|
}
|
|
|
|
+ connection->status = RPC_STATUS_ACTIVE;
|
|
return connection;
|
|
}
|
|
|
|
@@ -1334,11 +1381,14 @@
|
|
int32_t msg_tag;
|
|
int error = rpc_message_recv_int32(&message, &msg_tag);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
if (msg_tag != RPC_MESSAGE_START)
|
|
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
|
|
+ return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
|
|
|
|
- return _rpc_dispatch(connection, &message);
|
|
+ int method = _rpc_dispatch(connection, &message);
|
|
+ if (method < 0)
|
|
+ return rpc_error(connection, method);
|
|
+ return method;
|
|
}
|
|
|
|
|
|
@@ -1443,6 +1493,8 @@
|
|
|
|
if (connection == NULL)
|
|
return RPC_ERROR_CONNECTION_NULL;
|
|
+ if (_rpc_status(connection) == RPC_STATUS_CLOSED)
|
|
+ return RPC_ERROR_CONNECTION_CLOSED;
|
|
|
|
rpc_message_t message;
|
|
rpc_message_init(&message, connection);
|
|
@@ -1459,24 +1511,24 @@
|
|
// send: <invoke> = MESSAGE_START <method-id> MESSAGE_END
|
|
int error = rpc_message_send_int32(&message, RPC_MESSAGE_START);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
error = rpc_message_send_int32(&message, method);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
error = rpc_message_send_int32(&message, RPC_MESSAGE_END);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
error = rpc_message_flush(&message);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
|
|
// wait: MESSAGE_ACK
|
|
int32_t msg_tag;
|
|
error = rpc_message_recv_int32(&message, &msg_tag);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
if (msg_tag != RPC_MESSAGE_ACK)
|
|
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
|
|
+ return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
|
|
|
|
// send optional arguments
|
|
va_list args;
|
|
@@ -1490,19 +1542,19 @@
|
|
error = rpc_message_send_args(&message, args);
|
|
va_end(args);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
error = rpc_message_flush(&message);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
|
|
// wait: MESSAGE_ACK
|
|
error = rpc_message_recv_int32(&message, &msg_tag);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
if (msg_tag != RPC_MESSAGE_ACK)
|
|
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
|
|
+ return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
|
|
}
|
|
-
|
|
+
|
|
return RPC_ERROR_NO_ERROR;
|
|
}
|
|
|
|
@@ -1513,6 +1565,8 @@
|
|
|
|
if (connection == NULL)
|
|
return RPC_ERROR_CONNECTION_NULL;
|
|
+ if (_rpc_status(connection) == RPC_STATUS_CLOSED)
|
|
+ return RPC_ERROR_CONNECTION_CLOSED;
|
|
|
|
rpc_message_t message;
|
|
rpc_message_init(&message, connection);
|
|
@@ -1523,15 +1577,15 @@
|
|
int error = rpc_message_recv_args(&message, args);
|
|
va_end(args);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
|
|
// send: MESSAGE_ACK
|
|
error = rpc_message_send_int32(&message, RPC_MESSAGE_ACK);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
error = rpc_message_flush(&message);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
|
|
return RPC_ERROR_NO_ERROR;
|
|
}
|
|
@@ -1547,6 +1601,8 @@
|
|
|
|
if (connection == NULL)
|
|
return RPC_ERROR_CONNECTION_NULL;
|
|
+ if (_rpc_status(connection) == RPC_STATUS_CLOSED)
|
|
+ return RPC_ERROR_CONNECTION_CLOSED;
|
|
|
|
rpc_message_init(&message, connection);
|
|
va_start(args, connection);
|
|
@@ -1559,11 +1615,11 @@
|
|
while (!done) {
|
|
error = rpc_message_recv_int32(&message, &msg_tag);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
switch (msg_tag) {
|
|
case RPC_MESSAGE_START:
|
|
if ((error = _rpc_dispatch(connection, &message)) < 0)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
break;
|
|
case RPC_MESSAGE_REPLY:
|
|
case RPC_MESSAGE_ACK:
|
|
@@ -1575,11 +1631,12 @@
|
|
int32_t error_code;
|
|
error = rpc_message_recv_int32(&message, &error_code);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
- return error_code;
|
|
+ return rpc_error(connection, error);
|
|
+ // return other-side error code
|
|
+ return rpc_error(connection, error_code);
|
|
}
|
|
default:
|
|
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
|
|
+ return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
|
|
}
|
|
}
|
|
|
|
@@ -1587,35 +1644,35 @@
|
|
|
|
// wait: <reply>
|
|
if (msg_tag != RPC_MESSAGE_REPLY)
|
|
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
|
|
+ return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
|
|
va_start(args, connection);
|
|
error = rpc_message_recv_args(&message, args);
|
|
va_end(args);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
error = rpc_message_recv_int32(&message, &msg_tag);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
if (msg_tag != RPC_MESSAGE_END)
|
|
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
|
|
+ return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
|
|
|
|
// send: MESSAGE_ACK
|
|
error = rpc_message_send_int32(&message, RPC_MESSAGE_ACK);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
error = rpc_message_flush(&message);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
|
|
// wait: MESSAGE_ACK (prepare for final ACK)
|
|
error = rpc_message_recv_int32(&message, &msg_tag);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
}
|
|
|
|
// wait: MESSAGE_ACK
|
|
if (msg_tag != RPC_MESSAGE_ACK)
|
|
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
|
|
+ return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
|
|
|
|
return RPC_ERROR_NO_ERROR;
|
|
}
|
|
@@ -1626,7 +1683,9 @@
|
|
D(bug("rpc_method_send_reply\n"));
|
|
|
|
if (connection == NULL)
|
|
- return RPC_ERROR_GENERIC;
|
|
+ return RPC_ERROR_CONNECTION_NULL;
|
|
+ if (_rpc_status(connection) == RPC_STATUS_CLOSED)
|
|
+ return RPC_ERROR_CONNECTION_CLOSED;
|
|
|
|
rpc_message_t message;
|
|
rpc_message_init(&message, connection);
|
|
@@ -1634,27 +1693,27 @@
|
|
// send: <reply> = MESSAGE_REPLY [ <method-args> ] MESSAGE_END
|
|
int error = rpc_message_send_int32(&message, RPC_MESSAGE_REPLY);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
va_list args;
|
|
va_start(args, connection);
|
|
error = rpc_message_send_args(&message, args);
|
|
va_end(args);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
error = rpc_message_send_int32(&message, RPC_MESSAGE_END);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
error = rpc_message_flush(&message);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
|
|
// wait: MESSAGE_ACK
|
|
int32_t msg_tag;
|
|
error = rpc_message_recv_int32(&message, &msg_tag);
|
|
if (error != RPC_ERROR_NO_ERROR)
|
|
- return error;
|
|
+ return rpc_error(connection, error);
|
|
if (msg_tag != RPC_MESSAGE_ACK)
|
|
- return RPC_ERROR_MESSAGE_TYPE_INVALID;
|
|
+ return rpc_error(connection, RPC_ERROR_MESSAGE_TYPE_INVALID);
|
|
|
|
return RPC_ERROR_NO_ERROR;
|
|
}
|
|
Index: src/rpc.h
|
|
===================================================================
|
|
--- src/rpc.h (révision 460)
|
|
+++ src/rpc.h (révision 466)
|
|
@@ -51,6 +51,13 @@
|
|
extern int rpc_wait_dispatch(rpc_connection_t *connection, int timeout) attribute_hidden;
|
|
extern int rpc_socket(rpc_connection_t *connection) attribute_hidden;
|
|
|
|
+enum {
|
|
+ RPC_STATUS_BROKEN = -1,
|
|
+ RPC_STATUS_CLOSED = 0,
|
|
+ RPC_STATUS_ACTIVE = 1,
|
|
+};
|
|
+extern int rpc_status(rpc_connection_t *connection) attribute_hidden;
|
|
+
|
|
// Message Passing
|
|
enum {
|
|
RPC_TYPE_INVALID = 0,
|