Пример #1
0
void message_dispatch(void)
{
	int msg_type;
	pid_t src;
	void *buf;
	size_t len;
	struct dispatch_fns *dfn;
	int n_handled;

	if (!received_signal) return;

	DEBUG(10,("message_dispatch: received_signal = %d\n", received_signal));

	received_signal = 0;

	while (message_recv(&msg_type, &src, &buf, &len)) {
		DEBUG(10,("message_dispatch: received msg_type=%d src_pid=%u\n",
			  msg_type, (unsigned int) src));
		n_handled = 0;
		for (dfn = dispatch_fns; dfn; dfn = dfn->next) {
			if (dfn->msg_type == msg_type) {
				DEBUG(10,("message_dispatch: processing message of type %d.\n", msg_type));
				dfn->fn(msg_type, src, buf, len);
				n_handled++;
			}
		}
		if (!n_handled) {
			DEBUG(5,("message_dispatch: warning: no handlers registed for "
				 "msg_type %d in pid%u\n",
				 msg_type, (unsigned int)getpid()));
		}
		SAFE_FREE(buf);
	}
}
Пример #2
0
static void *
juggling_thread(void *arg)
{
	int fd2, i, j;

	fd2 = *(int *)arg;

	if (pthread_mutex_lock(&threaded_mtx) != 0)
		err(-1, "juggling_thread: pthread_mutex_lock");

	threaded_child_ready = 1;

	if (pthread_cond_signal(&threaded_cond) != 0)
		err(-1, "juggling_thread: pthread_cond_signal");

	if (pthread_mutex_unlock(&threaded_mtx) != 0)
		err(-1, "juggling_thread: pthread_mutex_unlock");

	for (i = 0; i < NUMCYCLES; i++) {
		for (j = 0; j < threaded_pipeline; j++) {
			if (message_recv(fd2) < 0)
				err(-1, "message_recv fd2");

			if (message_send(fd2) < 0)
				err(-1, "message_send fd2");
		}
	}

	return (NULL);
}
Пример #3
0
static struct timespec
thread_juggle(int fd1, int fd2, int pipeline)
{
	struct timespec tstart, tfinish;
	pthread_t thread;
	int i, j;

	threaded_pipeline = pipeline;

	if (pthread_mutex_init(&threaded_mtx, NULL) != 0)
		err(-1, "thread_juggle: pthread_mutex_init");

	if (pthread_create(&thread, NULL, juggling_thread, &fd2) != 0)
		err(-1, "thread_juggle: pthread_create");

	if (pthread_mutex_lock(&threaded_mtx) != 0)
		err(-1, "thread_juggle: pthread_mutex_lock");

	while (!threaded_child_ready) {
		if (pthread_cond_wait(&threaded_cond, &threaded_mtx) != 0)
			err(-1, "thread_juggle: pthread_cond_wait");
	}

	if (pthread_mutex_unlock(&threaded_mtx) != 0)
		err(-1, "thread_juggle: pthread_mutex_unlock");

	if (clock_gettime(CLOCK_REALTIME, &tstart) < 0)
		err(-1, "thread_juggle: clock_gettime");

	for (i = 0; i < NUMCYCLES; i++) {
		for (j = 0; j < pipeline; j++) {
			if (message_send(fd1) < 0)
				err(-1, "message_send fd1");
		}

		for (j = 0; j < pipeline; j++) {
			if (message_recv(fd1) < 0)
				err(-1, "message_recv fd1");
		}
	}

	if (clock_gettime(CLOCK_REALTIME, &tfinish) < 0)
		err(-1, "thread_juggle: clock_gettime");

	if (pthread_join(thread, NULL) != 0)
		err(-1, "thread_juggle: pthread_join");

	timespecsub(&tfinish, &tstart);

	return (tfinish);
}
Пример #4
0
/*
 * Juggle messages between two file descriptors in a single thread/process,
 * so simply a measure of IPC performance.
 */
static struct timespec
juggle(int fd1, int fd2, int pipeline)
{
	struct timespec tstart, tfinish;
	int i, j;

	if (clock_gettime(CLOCK_REALTIME, &tstart) < 0)
		err(-1, "juggle: clock_gettime");

	for (i = 0; i < NUMCYCLES; i++) {

		for (j = 0; j < pipeline; j++) {
			if (message_send(fd1) < 0)
				err(-1, "message_send fd1");
		}

		for (j = 0; j < pipeline; j++) {
			if (message_recv(fd2) < 0)
				err(-1, "message_recv fd2");

			if (message_send(fd2) < 0)
				err(-1, "message_send fd2");
		}

		for (j = 0; j < pipeline; j++) {
			if (message_recv(fd1) < 0)
				err(-1, "message_recv fd1");
		}
	}

	if (clock_gettime(CLOCK_REALTIME, &tfinish) < 0)
		err(-1, "juggle: clock_gettime");

	timespecsub(&tfinish, &tstart);

	return (tfinish);
}
Пример #5
0
void message_dispatch(void)
{
	int msg_type;
	struct process_id src;
	char *buf;
	char *msgs_buf;
	size_t len, total_len;
	struct dispatch_fns *dfn;
	int n_handled;

	if (!received_signal)
		return;

	DEBUG(10,("message_dispatch: received_signal = %d\n", received_signal));

	received_signal = 0;

	if (!retrieve_all_messages(&msgs_buf, &total_len))
		return;

	for (buf = msgs_buf; message_recv(msgs_buf, total_len, &msg_type, &src, &buf, &len); buf += len) {
		DEBUG(10,("message_dispatch: received msg_type=%d "
			  "src_pid=%u\n", msg_type,
			  (unsigned int) procid_to_pid(&src)));
		n_handled = 0;
		for (dfn = dispatch_fns; dfn; dfn = dfn->next) {
			if (dfn->msg_type == msg_type) {
				DEBUG(10,("message_dispatch: processing message of type %d.\n", msg_type));
				dfn->fn(msg_type, src, len ? (void *)buf : NULL, len);
				n_handled++;
			}
		}
		if (!n_handled) {
			DEBUG(5,("message_dispatch: warning: no handlers registed for "
				 "msg_type %d in pid %u\n",
				 msg_type, (unsigned int)sys_getpid()));
		}
	}
	SAFE_FREE(msgs_buf);
}
Пример #6
0
/**
 * Sends the given class to the remote server for instrumentation. If the
 * server modified the class, provided class definition structure is updated
 * and the function returns TRUE. Otherwise, the structure is left unmodified
 * and FALSE is returned.
 *
 * NOTE: The class_name parameter may be NULL -- this is often the case for
 * anonymous classes.
 */
static bool
__instrument_class (
	jint request_flags, const char * class_name,
	jvmtiClassDefinition * class_def
) {
	//
	// Put the class data into a request message, acquire a connection and
	// send the it to the server. Receive the response and release the
	// connection again.
	//
	struct message request = {
		.message_flags = request_flags,
		.control_size = (class_name != NULL) ? strlen (class_name) : 0,
		.classcode_size = class_def->class_byte_count,
		.control = (unsigned char *) class_name,
		.classcode = class_def->class_bytes,
	};

	//

	struct connection * conn = network_acquire_connection ();
	message_send (conn, &request);

	struct message response;
	message_recv (conn, &response);
	network_release_connection (conn);

	//
	// Check if error occurred on the server.
	// The control field of the response contains the error message.
	//
	if (response.control_size > 0) {
		fprintf (
			stderr, "%sinstrumentation server error:\n%s\n",
			ERROR_PREFIX, response.control
		);

		exit (ERROR_SERVER);
	}

	//
	// Update the class definition and signal that the class has been
	// modified if non-empty class code has been returned. Otherwise,
	// signal that the class has not been modified.
	//
	if (response.classcode_size > 0) {
		class_def->class_byte_count = response.classcode_size;
		class_def->class_bytes = response.classcode;
		return true;

	} else {
		return false;
	}
}


static void
__handle_exception (JNIEnv * jni, jthrowable ex_obj) {
	jclass ex_class = (* jni)->GetObjectClass (jni, ex_obj);
	jmethodID m_getClass = (* jni)->GetMethodID (jni, ex_class, "getClass", "()Ljava/lang/Class;");
	jobject cl_obj = (* jni)->CallObjectMethod (jni, ex_obj, m_getClass);

	jclass cl_class = (* jni)->GetObjectClass (jni, cl_obj);
	jmethodID m_getName = (* jni)->GetMethodID (jni, cl_class, "getName", "()Ljava/lang/String;");
	jstring cl_name = (* jni)->CallObjectMethod (jni, cl_obj, m_getName);

	const char * cl_name_chars = (* jni)->GetStringUTFChars (jni, cl_name, NULL);
	rdaprintf ("\texception %s occured, cleared\n", cl_name_chars);
	(* jni)->ReleaseStringUTFChars (jni, cl_name, cl_name_chars);
}
Пример #7
0
static void child (int conn, fsp_backend *backend, fs_backend *be)
{
  int auth = 0;

  while (1) {
    fs_segment segment;
    unsigned int length;
    unsigned char *msg = message_recv(conn, &segment, &length);
    unsigned char *reply = NULL;
    unsigned char *content = msg + FS_HEADER;

    if (!msg) {
      /* if the connection is in fact closed, this won't matter,
         but otherwise this error might help */
      reply = fsp_error_new(segment, "protocol mismatch");
      unsigned int* const l = (unsigned int *) (reply + 4);
      unsigned int length = *l;
      if (write(conn, reply, FS_HEADER + length) != (FS_HEADER+length)) {
        fs_error(LOG_ERR, "write failed: %s", strerror(errno));
      }
      break;
    }

    if (auth) {
      switch (msg[3]) {
        case FS_NO_OP:
          reply = fsp_handle_no_op(segment, length, content);
          break;
        case FS_RESOLVE:
          reply = handle(backend->resolve, be, segment, length, content);
          break;
        case FS_BIND:
          reply = handle(backend->bind, be, segment, length, content);
          break;
        case FS_PRICE_BIND:
          reply = handle(backend->price, be, segment, length, content);
          break;
        case FS_DELETE_MODEL:
          reply = handle(backend->delete_models, be, segment, length, content);
          break;
        case FS_INSERT_RESOURCE:
          reply = handle(backend->insert_resource, be, segment, length, content);
          break;
        case FS_SEGMENTS:
          reply = handle(backend->segments, be, segment, length, content);
          break;
        case FS_COMMIT_RESOURCE:
          reply = handle(backend->commit_resource, be, segment, length, content);
          break;
        case FS_START_IMPORT:
          reply = handle(backend->start_import, be, segment, length, content);
          break;
        case FS_STOP_IMPORT:
          reply = handle(backend->stop_import, be, segment, length, content);
          break;
        case FS_GET_SIZE:
          reply = handle(backend->get_data_size, be, segment, length, content);
          break;
        case FS_GET_IMPORT_TIMES:
          reply = handle(backend->get_import_times, be, segment, length, content);
          break;
        case FS_INSERT_QUAD:
          reply = handle(backend->insert_quad, be, segment, length, content);
          break;
        case FS_COMMIT_QUAD:
          reply = handle(backend->commit_quad, be, segment, length, content);
          break;
        case FS_GET_QUERY_TIMES:
          reply = handle(backend->get_query_times, be, segment, length, content);
          break;
        case FS_BIND_LIMIT:
          reply = handle(backend->bind_limit, be, segment, length, content);
          break;
        case FS_BNODE_ALLOC:
          reply = handle(backend->bnode_alloc, be, segment, length, content);
          break;
        case FS_RESOLVE_ATTR:
          reply = handle(backend->resolve_attr, be, segment, length, content);
          break;
        case FS_DELETE_MODELS:
          reply = handle(backend->delete_models, be, segment, length, content);
          break;
        case FS_NEW_MODELS:
          reply = handle(backend->new_models, be, segment, length, content);
          break;
        case FS_BIND_FIRST:
          reply = handle(backend->bind_first, be, segment, length, content);
          break;
        case FS_BIND_NEXT:
          reply = handle(backend->bind_next, be, segment, length, content);
          break;
        case FS_BIND_DONE:
          reply = handle(backend->bind_done, be, segment, length, content);
          break;
        case FS_TRANSACTION:
          reply = handle(backend->transaction, be, segment, length, content);
          break;
        case FS_NODE_SEGMENTS:
          reply = handle(backend->node_segments, be, segment, length, content);
          break;
        case FS_REVERSE_BIND:
          reply = handle(backend->reverse_bind, be, segment, length, content);
          break;
        case FS_LOCK:
          reply = handle(backend->lock, be, segment, length, content);
          break;
        case FS_UNLOCK:
          reply = handle(backend->unlock, be, segment, length, content);
          break;
        case FS_GET_SIZE_REVERSE:
          reply = handle(backend->get_size_reverse, be, segment, length, content);
          break;
        case FS_GET_QUAD_FREQ:
          reply = handle(backend->get_quad_freq, be, segment, length, content);
          break;
        case FS_CHOOSE_SEGMENT:
          reply = handle(backend->choose_segment, be, segment, length, content);
          break;
	case FS_DELETE_QUADS:
	  reply = handle(backend->delete_quads, be, segment, length, content);
	  break;
	case FS_GET_UUID:
	  reply = handle(backend->get_uuid, be, segment, length, content);
	  break;
        default:
          kb_error(LOG_WARNING, "unexpected message type (%d)", msg[3]);
          reply = fsp_error_new(segment, "unexpected message type");
          break;
      }
    } else if (msg[3] == FS_AUTH) {
      if (backend->auth) {
        reply = backend->auth(be, segment, length, content);
      } else {
        reply = message_new(FS_DONE_OK, segment, 0);
      }
      if (reply[3] == FS_DONE_OK) auth = 1;
    } else  {
      reply = fsp_error_new(segment, "authenticate before continuing");
    }

    if (reply) {
      unsigned int* const l = (unsigned int *) (reply + 4);
      unsigned int length = *l;
      if (write(conn, reply, FS_HEADER + length) <= 0) {
        kb_error(LOG_WARNING, "write reply failed");
      }
      free(reply);
    }
    free(msg);
  }
}
Пример #8
0
/*
 * Juggle messages between two file descriptors in two processes, so measure
 * the cost of IPC and the cost of a process context switch.
 *
 * Since we can't use a mutex between the processes, we simply do an extra
 * write on the child to let the parent know that it's ready to start.
 */
static struct timespec
process_juggle(int fd1, int fd2, int pipeline)
{
	struct timespec tstart, tfinish;
	pid_t pid, ppid, wpid;
	int error, i, j;

	ppid = getpid();

	pid = fork();
	if (pid < 0)
		err(-1, "process_juggle: fork");

	if (pid == 0) {
		if (message_send(fd2) < 0) {
			error = errno;
			kill(ppid, SIGTERM);
			errno = error;
			err(-1, "process_juggle: child: message_send");
		}

		for (i = 0; i < NUMCYCLES; i++) {
			for (j = 0; j < pipeline; j++) {
				if (message_send(fd2) < 0)
					err(-1, "message_send fd2");

				if (message_recv(fd2) < 0)
					err(-1, "message_recv fd2");
			}
		}

		exit(0);
	} else {
		if (message_recv(fd1) < 0) {
			error = errno;
			kill(pid, SIGTERM);
			errno = error;
			err(-1, "process_juggle: parent: message_recv");
		}

		if (clock_gettime(CLOCK_REALTIME, &tstart) < 0)
			err(-1, "process_juggle: clock_gettime");

		for (i = 0; i < NUMCYCLES; i++) {
			for (j = 0; j < pipeline; j++) {
				if (message_send(fd1) < 0) {
					error = errno;
					kill(pid, SIGTERM);
					errno = error;
					err(-1, "message_send fd1");
				}
			}

			for (j = 0; j < pipeline; j++) {
				if (message_recv(fd1) < 0) {
					error = errno;
					kill(pid, SIGTERM);
					errno = error;
					err(-1, "message_recv fd1");
				}
			}
		}

		if (clock_gettime(CLOCK_REALTIME, &tfinish) < 0)
			err(-1, "process_juggle: clock_gettime");
	}

	wpid = waitpid(pid, NULL, 0);
	if (wpid < 0)
		err(-1, "process_juggle: waitpid");
	if (wpid != pid)
		errx(-1, "process_juggle: waitpid: pid != wpid");

	timespecsub(&tfinish, &tstart);

	return (tfinish);
}