/* * Gets a reply from the MongoDB server and * creates a cursor for it */ int mongo_link_hear(SV *cursor_sv) { int sock; int num_returned = 0; mongo_cursor *cursor = (mongo_cursor*)perl_mongo_get_ptr_from_instance(cursor_sv); SV *link_sv = perl_mongo_call_reader(cursor_sv, "_connection"); mongo_link *link = (mongo_link*)perl_mongo_get_ptr_from_instance(link_sv); if (!check_connection(link)) { croak("can't get db response, not connected"); return 0; } sock = perl_mongo_link_master(link_sv); // if this fails, we might be disconnected... but we're probably // just out of results if (recv(sock, (char*)&cursor->header.length, INT_32, 0) == -1) { return 0; } // make sure we're not getting crazy data if (cursor->header.length > MAX_RESPONSE_LEN || cursor->header.length < REPLY_HEADER_SIZE) { set_disconnected(link); if (!check_connection(link)) { croak("bad response length: %d, max: %d, did the db assert?\n", cursor->header.length, MAX_RESPONSE_LEN); return 0; } } if (recv(sock, (char*)&cursor->header.request_id, INT_32, 0) == -1 || recv(sock, (char*)&cursor->header.response_to, INT_32, 0) == -1 || recv(sock, (char*)&cursor->header.op, INT_32, 0) == -1 || recv(sock, (char*)&cursor->flag, INT_32, 0) == -1 || recv(sock, (char*)&cursor->cursor_id, INT_64, 0) == -1 || recv(sock, (char*)&cursor->start, INT_32, 0) == -1 || recv(sock, (char*)&num_returned, INT_32, 0) == -1) { return 0; } // create buf cursor->header.length -= INT_32*9; // point buf.start at buf's first char if (!cursor->buf.start) { Newx(cursor->buf.start, cursor->header.length, char); cursor->buf.end = cursor->buf.start + cursor->header.length; }
/* * Sends a message to the MongoDB server */ int mongo_link_say(SV *link_sv, buffer *buf) { int sock, sent; mongo_link *link = (mongo_link*)perl_mongo_get_ptr_from_instance(link_sv); if (!check_connection(link)) { croak("can't get db response, not connected"); return -1; } sock = perl_mongo_link_master(link_sv); sent = send(sock, (const char*)buf->start, buf->pos-buf->start, 0); if (sent == -1) { if (check_connection(link)) { sock = perl_mongo_link_master(link_sv); sent = send(sock, (const char*)buf->start, buf->pos-buf->start, 0); } else { return -1; } } return sent; }