ipc_shm.c | ipc_shm.c | |||
---|---|---|---|---|
skipping to change at line 26 | skipping to change at line 26 | |||
* GNU Lesser General Public License for more details. | * GNU Lesser General Public License for more details. | |||
* | * | |||
* You should have received a copy of the GNU Lesser General Public License | * You should have received a copy of the GNU Lesser General Public License | |||
* along with libqb. If not, see <http://www.gnu.org/licenses/>. | * along with libqb. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | */ | |||
#include "os_base.h" | #include "os_base.h" | |||
#include "ipc_int.h" | #include "ipc_int.h" | |||
#include "util_int.h" | #include "util_int.h" | |||
#include <qb/qbdefs.h> | #include <qb/qbdefs.h> | |||
#include <qb/qbatomic.h> | ||||
#include <qb/qbloop.h> | #include <qb/qbloop.h> | |||
#include <qb/qbrb.h> | #include <qb/qbrb.h> | |||
/* | /* | |||
* utility functions | * utility functions | |||
* -------------------------------------------------------- | * -------------------------------------------------------- | |||
*/ | */ | |||
/* | /* | |||
* client functions | * client functions | |||
* -------------------------------------------------------- | * -------------------------------------------------------- | |||
*/ | */ | |||
static void qb_ipcc_shm_disconnect(struct qb_ipcc_connection *c) | static void | |||
qb_ipcc_shm_disconnect(struct qb_ipcc_connection *c) | ||||
{ | { | |||
qb_rb_close(c->request.u.shm.rb); | qb_rb_close(c->request.u.shm.rb); | |||
qb_rb_close(c->response.u.shm.rb); | qb_rb_close(c->response.u.shm.rb); | |||
qb_rb_close(c->event.u.shm.rb); | qb_rb_close(c->event.u.shm.rb); | |||
} | } | |||
static ssize_t qb_ipc_shm_send(struct qb_ipc_one_way *one_way, | static ssize_t | |||
const void *msg_ptr, size_t msg_len) | qb_ipc_shm_send(struct qb_ipc_one_way *one_way, | |||
const void *msg_ptr, size_t msg_len) | ||||
{ | { | |||
return qb_rb_chunk_write(one_way->u.shm.rb, msg_ptr, msg_len); | return qb_rb_chunk_write(one_way->u.shm.rb, msg_ptr, msg_len); | |||
} | } | |||
static ssize_t qb_ipc_shm_sendv(struct qb_ipc_one_way *one_way, | static ssize_t | |||
const struct iovec* iov, | qb_ipc_shm_sendv(struct qb_ipc_one_way *one_way, | |||
size_t iov_len) | const struct iovec *iov, size_t iov_len) | |||
{ | { | |||
char *dest; | char *dest; | |||
int32_t res = 0; | int32_t res = 0; | |||
int32_t total_size = 0; | int32_t total_size = 0; | |||
int32_t i; | int32_t i; | |||
char *pt = NULL; | char *pt = NULL; | |||
if (one_way->u.shm.rb == NULL) { | if (one_way->u.shm.rb == NULL) { | |||
return -ENOTCONN; | return -ENOTCONN; | |||
} | } | |||
skipping to change at line 84 | skipping to change at line 87 | |||
memcpy(pt, iov[i].iov_base, iov[i].iov_len); | memcpy(pt, iov[i].iov_base, iov[i].iov_len); | |||
pt += iov[i].iov_len; | pt += iov[i].iov_len; | |||
} | } | |||
res = qb_rb_chunk_commit(one_way->u.shm.rb, total_size); | res = qb_rb_chunk_commit(one_way->u.shm.rb, total_size); | |||
if (res < 0) { | if (res < 0) { | |||
return res; | return res; | |||
} | } | |||
return total_size; | return total_size; | |||
} | } | |||
static ssize_t qb_ipc_shm_recv(struct qb_ipc_one_way *one_way, | static ssize_t | |||
void *msg_ptr, | qb_ipc_shm_recv(struct qb_ipc_one_way *one_way, | |||
size_t msg_len, | void *msg_ptr, size_t msg_len, int32_t ms_timeout) | |||
int32_t ms_timeout) | ||||
{ | { | |||
if (one_way->u.shm.rb == NULL) { | if (one_way->u.shm.rb == NULL) { | |||
return -ENOTCONN; | return -ENOTCONN; | |||
} | } | |||
return qb_rb_chunk_read(one_way->u.shm.rb, | return qb_rb_chunk_read(one_way->u.shm.rb, | |||
(void *)msg_ptr, | (void *)msg_ptr, msg_len, ms_timeout); | |||
msg_len, | ||||
ms_timeout); | ||||
} | } | |||
static ssize_t qb_ipc_shm_peek(struct qb_ipc_one_way *one_way, void **data_ | static ssize_t | |||
out, int32_t ms_timeout) | qb_ipc_shm_peek(struct qb_ipc_one_way *one_way, void **data_out, | |||
int32_t ms_timeout) | ||||
{ | { | |||
if (one_way->u.shm.rb == NULL) { | if (one_way->u.shm.rb == NULL) { | |||
return -ENOTCONN; | return -ENOTCONN; | |||
} | } | |||
return qb_rb_chunk_peek(one_way->u.shm.rb, | return qb_rb_chunk_peek(one_way->u.shm.rb, data_out, ms_timeout); | |||
data_out, | ||||
ms_timeout); | ||||
} | } | |||
static void qb_ipc_shm_reclaim(struct qb_ipc_one_way *one_way) | static void | |||
qb_ipc_shm_reclaim(struct qb_ipc_one_way *one_way) | ||||
{ | { | |||
if (one_way->u.shm.rb != NULL) { | if (one_way->u.shm.rb != NULL) { | |||
qb_rb_chunk_reclaim(one_way->u.shm.rb); | qb_rb_chunk_reclaim(one_way->u.shm.rb); | |||
} | } | |||
} | } | |||
static void qb_ipc_shm_fc_set(struct qb_ipc_one_way *one_way, | static void | |||
int32_t fc_enable) | qb_ipc_shm_fc_set(struct qb_ipc_one_way *one_way, int32_t fc_enable) | |||
{ | { | |||
int32_t *fc; | int32_t *fc; | |||
fc = qb_rb_shared_user_data_get(one_way->u.shm.rb); | fc = qb_rb_shared_user_data_get(one_way->u.shm.rb); | |||
*fc = fc_enable; | qb_util_log(LOG_TRACE, "setting fc to %d", fc_enable); | |||
qb_atomic_int_set(fc, fc_enable); | ||||
} | } | |||
static int32_t qb_ipc_shm_fc_get(struct qb_ipc_one_way *one_way) | static int32_t | |||
qb_ipc_shm_fc_get(struct qb_ipc_one_way *one_way) | ||||
{ | { | |||
int32_t *fc; | int32_t *fc; | |||
int32_t rc = qb_rb_refcount_get(one_way->u.shm.rb); | int32_t rc = qb_rb_refcount_get(one_way->u.shm.rb); | |||
if (rc != 2) { | if (rc != 2) { | |||
return -ENOTCONN; | return -ENOTCONN; | |||
} | } | |||
fc = qb_rb_shared_user_data_get(one_way->u.shm.rb); | fc = qb_rb_shared_user_data_get(one_way->u.shm.rb); | |||
return *fc; | return qb_atomic_int_get(fc); | |||
} | } | |||
static ssize_t qb_ipc_shm_q_len_get(struct qb_ipc_one_way *one_way) | static ssize_t | |||
qb_ipc_shm_q_len_get(struct qb_ipc_one_way *one_way) | ||||
{ | { | |||
if (one_way->u.shm.rb == NULL) { | if (one_way->u.shm.rb == NULL) { | |||
return -ENOTCONN; | return -ENOTCONN; | |||
} | } | |||
return qb_rb_chunks_used(one_way->u.shm.rb); | return qb_rb_chunks_used(one_way->u.shm.rb); | |||
} | } | |||
int32_t qb_ipcc_shm_connect(struct qb_ipcc_connection *c, | int32_t | |||
struct qb_ipc_connection_response *response) | qb_ipcc_shm_connect(struct qb_ipcc_connection * c, | |||
struct qb_ipc_connection_response * response) | ||||
{ | { | |||
int32_t res = 0; | int32_t res = 0; | |||
c->funcs.send = qb_ipc_shm_send; | c->funcs.send = qb_ipc_shm_send; | |||
c->funcs.sendv = qb_ipc_shm_sendv; | c->funcs.sendv = qb_ipc_shm_sendv; | |||
c->funcs.recv = qb_ipc_shm_recv; | c->funcs.recv = qb_ipc_shm_recv; | |||
c->funcs.fc_get = qb_ipc_shm_fc_get; | c->funcs.fc_get = qb_ipc_shm_fc_get; | |||
c->funcs.disconnect = qb_ipcc_shm_disconnect; | c->funcs.disconnect = qb_ipcc_shm_disconnect; | |||
c->needs_sock_for_poll = QB_TRUE; | c->needs_sock_for_poll = QB_TRUE; | |||
if (strlen(c->name) > (NAME_MAX - 20)) { | if (strlen(c->name) > (NAME_MAX - 20)) { | |||
errno = EINVAL; | errno = EINVAL; | |||
return -errno; | return -errno; | |||
} | } | |||
c->request.u.shm.rb = qb_rb_open(response->request, c->request.max_m | c->request.u.shm.rb = | |||
sg_size, | qb_rb_open(response->request, c->request.max_msg_size, | |||
QB_RB_FLAG_SHARED_PROCESS, | QB_RB_FLAG_SHARED_PROCESS, sizeof(int32_t)); | |||
sizeof(int32_t)); | ||||
if (c->request.u.shm.rb == NULL) { | if (c->request.u.shm.rb == NULL) { | |||
res = -errno; | res = -errno; | |||
goto return_error; | goto return_error; | |||
} | } | |||
c->response.u.shm.rb = qb_rb_open(response->response, | c->response.u.shm.rb = qb_rb_open(response->response, | |||
c->response.max_msg_size, | c->response.max_msg_size, | |||
QB_RB_FLAG_SHARED_PROCESS, 0); | QB_RB_FLAG_SHARED_PROCESS, 0); | |||
if (c->response.u.shm.rb == NULL) { | if (c->response.u.shm.rb == NULL) { | |||
res = -errno; | res = -errno; | |||
skipping to change at line 187 | skipping to change at line 192 | |||
c->response.max_msg_size, | c->response.max_msg_size, | |||
QB_RB_FLAG_SHARED_PROCESS, 0); | QB_RB_FLAG_SHARED_PROCESS, 0); | |||
if (c->event.u.shm.rb == NULL) { | if (c->event.u.shm.rb == NULL) { | |||
res = -errno; | res = -errno; | |||
perror("qb_rb_open:EVENT"); | perror("qb_rb_open:EVENT"); | |||
goto cleanup_request_response; | goto cleanup_request_response; | |||
} | } | |||
return 0; | return 0; | |||
cleanup_request_response: | cleanup_request_response: | |||
qb_rb_close(c->response.u.shm.rb); | qb_rb_close(c->response.u.shm.rb); | |||
cleanup_request: | cleanup_request: | |||
qb_rb_close(c->request.u.shm.rb); | qb_rb_close(c->request.u.shm.rb); | |||
return_error: | return_error: | |||
qb_util_log(LOG_ERR, "connection failed %s", | errno = -res; | |||
strerror(-res)); | qb_util_perror(LOG_ERR, "connection failed"); | |||
return res; | return res; | |||
} | } | |||
/* | /* | |||
* service functions | * service functions | |||
* -------------------------------------------------------- | * -------------------------------------------------------- | |||
*/ | */ | |||
static void qb_ipcs_shm_disconnect(struct qb_ipcs_connection *c) | static void | |||
qb_ipcs_shm_disconnect(struct qb_ipcs_connection *c) | ||||
{ | { | |||
struct qb_ipc_response_header msg; | struct qb_ipc_response_header msg; | |||
int32_t peer_alive = QB_TRUE; | ||||
if (c->setup.u.us.sock == -1) { | ||||
peer_alive = QB_FALSE; | ||||
} | ||||
msg.id = QB_IPC_MSG_DISCONNECT; | msg.id = QB_IPC_MSG_DISCONNECT; | |||
msg.size = sizeof(msg); | msg.size = sizeof(msg); | |||
msg.error = 0; | msg.error = 0; | |||
if (c->response.u.shm.rb) { | if (c->response.u.shm.rb) { | |||
qb_rb_close(c->response.u.shm.rb); | qb_rb_close(c->response.u.shm.rb); | |||
c->response.u.shm.rb = NULL; | c->response.u.shm.rb = NULL; | |||
} | } | |||
if (c->event.u.shm.rb) { | if (c->event.u.shm.rb) { | |||
qb_rb_close(c->event.u.shm.rb); | qb_rb_close(c->event.u.shm.rb); | |||
c->event.u.shm.rb = NULL; | c->event.u.shm.rb = NULL; | |||
} | } | |||
if (c->request.u.shm.rb) { | if (c->request.u.shm.rb) { | |||
qb_rb_close(c->request.u.shm.rb); | qb_rb_close(c->request.u.shm.rb); | |||
c->request.u.shm.rb = NULL; | c->request.u.shm.rb = NULL; | |||
} | } | |||
} | } | |||
static int32_t qb_ipcs_shm_connect(struct qb_ipcs_service *s, | static int32_t | |||
struct qb_ipcs_connection *c, | qb_ipcs_shm_connect(struct qb_ipcs_service *s, | |||
struct qb_ipc_connection_response *r) | struct qb_ipcs_connection *c, | |||
struct qb_ipc_connection_response *r) | ||||
{ | { | |||
int32_t res; | int32_t res; | |||
qb_util_log(LOG_DEBUG, "connecting to client [%d]", c->pid); | qb_util_log(LOG_DEBUG, "connecting to client [%d]", c->pid); | |||
snprintf(r->request, NAME_MAX, "qb-%s-request-%d-%d", s->name, c->pi | snprintf(r->request, NAME_MAX, "%s-request-%d-%d", s->name, c->pid, | |||
d, c->setup.u.us.sock); | c->setup.u.us.sock); | |||
snprintf(r->response, NAME_MAX, "qb-%s-response-%d-%d", s->name, c-> | snprintf(r->response, NAME_MAX, "%s-response-%d-%d", s->name, c->pid | |||
pid, c->setup.u.us.sock); | , | |||
snprintf(r->event, NAME_MAX, "qb-%s-event-%d-%d", s->name, c->pid, c | c->setup.u.us.sock); | |||
->setup.u.us.sock); | snprintf(r->event, NAME_MAX, "%s-event-%d-%d", s->name, c->pid, | |||
c->setup.u.us.sock); | ||||
c->request.u.shm.rb = qb_rb_open(r->request, | c->request.u.shm.rb = qb_rb_open(r->request, | |||
c->request.max_msg_size, | c->request.max_msg_size, | |||
QB_RB_FLAG_CREATE | | QB_RB_FLAG_CREATE | | |||
QB_RB_FLAG_SHARED_PROCESS, | QB_RB_FLAG_SHARED_PROCESS, | |||
sizeof(int32_t)); | sizeof(int32_t)); | |||
if (c->request.u.shm.rb == NULL) { | if (c->request.u.shm.rb == NULL) { | |||
res = -errno; | res = -errno; | |||
perror("qb_rb_open:REQUEST"); | perror("qb_rb_open:REQUEST"); | |||
goto cleanup; | goto cleanup; | |||
skipping to change at line 290 | skipping to change at line 295 | |||
return 0; | return 0; | |||
cleanup_request_response: | cleanup_request_response: | |||
qb_rb_close(c->request.u.shm.rb); | qb_rb_close(c->request.u.shm.rb); | |||
cleanup_request: | cleanup_request: | |||
qb_rb_close(c->response.u.shm.rb); | qb_rb_close(c->response.u.shm.rb); | |||
cleanup: | cleanup: | |||
r->hdr.error = res; | r->hdr.error = res; | |||
qb_util_log(LOG_ERR, "shm connection FAILED [%s]", | errno = -res; | |||
strerror(-res)); | qb_util_perror(LOG_ERR, "shm connection FAILED"); | |||
return res; | return res; | |||
} | } | |||
void qb_ipcs_shm_init(struct qb_ipcs_service *s) | void | |||
qb_ipcs_shm_init(struct qb_ipcs_service *s) | ||||
{ | { | |||
s->funcs.connect = qb_ipcs_shm_connect; | s->funcs.connect = qb_ipcs_shm_connect; | |||
s->funcs.disconnect = qb_ipcs_shm_disconnect; | s->funcs.disconnect = qb_ipcs_shm_disconnect; | |||
s->funcs.recv = qb_ipc_shm_recv; | s->funcs.recv = qb_ipc_shm_recv; | |||
s->funcs.peek = qb_ipc_shm_peek; | s->funcs.peek = qb_ipc_shm_peek; | |||
s->funcs.reclaim = qb_ipc_shm_reclaim; | s->funcs.reclaim = qb_ipc_shm_reclaim; | |||
s->funcs.send = qb_ipc_shm_send; | s->funcs.send = qb_ipc_shm_send; | |||
s->funcs.sendv = qb_ipc_shm_sendv; | s->funcs.sendv = qb_ipc_shm_sendv; | |||
End of changes. 25 change blocks. | ||||
54 lines changed or deleted | 56 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |