Esempio n. 1
0
int main(int argc, char * argv[]) {
  setlocale(LC_ALL, "");

  ab::ui::UiGameClientIpc ipc;

  QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
  QApplication app(argc, argv);
  GameFieldView fieldView(ipc);
  
  std::thread network_client_thread(network_client, "localhost", 1234, std::ref(ipc));
  std::thread ui_updater_thread([&]() {
      ab::ui::ConnectionState last_state = static_cast<ab::ui::ConnectionState>(-1);
      std::unique_lock<std::mutex> ipc_lock(ipc.mutex);
      while (true) {
        if (last_state != ipc.connection_state) {
          std::cerr << "state: " << ipc.connection_state << std::endl;
          last_state = ipc.connection_state;
        }
        QMetaObject::invokeMethod(&fieldView, "updateFieldView");
        if (ipc.connection_state == ab::ui::ConnectionState::disconnected) {
          return;
        }
        ipc.cv.wait(ipc_lock);
      }
    });

  fieldView.show();
  app.exec();

  ui_updater_thread.join();
  network_client_thread.join();
  return 0;
}
Esempio n. 2
0
/*
 * shm_lock_(check_) routines are called in the paths where the rw_mutex
 * is not necessarily held.
 */
static inline struct shmid_kernel *shm_lock(struct ipc_namespace *ns, int id)
{
	struct kern_ipc_perm *ipcp = ipc_lock(&shm_ids(ns), id);

	if (IS_ERR(ipcp))
		return (struct shmid_kernel *)ipcp;

	return container_of(ipcp, struct shmid_kernel, shm_perm);
}
Esempio n. 3
0
/*
 * sem_lock_(check_) routines are called in the paths where the rw_mutex
 * is not held.
 */
static inline struct sem_array *sem_lock(struct ipc_namespace *ns, int id)
{
	struct kern_ipc_perm *ipcp = ipc_lock(&sem_ids(ns), id);

	if (IS_ERR(ipcp))
		return (struct sem_array *)ipcp;

	return container_of(ipcp, struct sem_array, sem_perm);
}
Esempio n. 4
0
/*
 * msg_lock_(check_) routines are called in the paths where the rw_mutex
 * is not held.
 */
static inline struct msg_queue *msg_lock(struct ipc_namespace *ns, int id)
{
	struct kern_ipc_perm *ipcp = ipc_lock(&msg_ids(ns), id);

	if (IS_ERR(ipcp))
		return (struct msg_queue *)ipcp;

	return container_of(ipcp, struct msg_queue, q_perm);
}
Esempio n. 5
0
/*
 * ipc_finish() -
 *
 *	Locks and destroys the semaphore set and message queue if called
 *	in the daemonized queue runner. If force isn't given, it will
 *	only do so if the archive queue is empty after locking the set
 *	and draining the message queue.
 */
int
ipc_finish(bool force)
{
	if (ipc_creator)
	{
		if (!force)
		{
			/*
			 * We are the creator of the semaphore set, so if this isn't
			 * a force operation, we lock it first, poll the message queue
			 * and check that we have an empty queue.
			 */
			if (ipc_lock() < 0)
			{
				fprintf(stderr, "semop() failed in ipc_finish(): %s\n",
						strerror(errno));
				return -1;
			}

			if (ipc_poll(false) < 0)
				return -1;
			
			if (archive_queue_head != NULL)
			{
				if (ipc_unlock() < 0)
				{
					fprintf(stderr, "semop() failed in ipc_finish(): %s\n",
							strerror(errno));
					return -1;
				}
				return 1;
			}
		}
		/*
		 * At this point, we are either forced to stop or we have a lock
		 * and the queue is empty.
		 */
		if (msgctl(msgid, IPC_RMID, NULL) < 0)
		{
			fprintf(stderr, "msgctl() failed in ipc_finish(): %s\n",
					strerror(errno));
			semctl(semid, 0, IPC_RMID);
			return -1;
		}

		if (semctl(semid, 0, IPC_RMID) < 0)
		{
			fprintf(stderr, "semctl() failed in ipc_finish(): %s\n",
					strerror(errno));
			return -1;
		}
	}

	return 0;
}
Esempio n. 6
0
/*
 * semexit - Called by exit() to clean up on process exit.
 */
void
semexit(proc_t *pp)
{
    avl_tree_t	*tree;
    struct sem_undo	*undo;
    void		*cookie = NULL;

    mutex_enter(&pp->p_lock);
    tree = pp->p_semacct;
    pp->p_semacct = NULL;
    mutex_exit(&pp->p_lock);

    while (undo = avl_destroy_nodes(tree, &cookie)) {
        ksemid_t *sp = undo->un_sp;
        size_t size = SEM_UNDOSZ(sp->sem_nsems);
        int i;

        (void) ipc_lock(sem_svc, sp->sem_perm.ipc_id);
        if (!IPC_FREE(&sp->sem_perm)) {
            for (i = 0; i < sp->sem_nsems; i++) {
                int adj = undo->un_aoe[i];
                if (adj) {
                    struct sem *semp = &sp->sem_base[i];
                    int v = (int)semp->semval + adj;

                    if (v < 0 || v > USHRT_MAX)
                        continue;
                    semp->semval = (ushort_t)v;
                    if (v == 0 && semp->semzcnt)
                        cv_broadcast(&semp->semzcnt_cv);
                    if (adj > 0 && semp->semncnt)
                        cv_broadcast(&semp->semncnt_cv);
                }
            }
            list_remove(&sp->sem_undos, undo);
        }
        ipc_rele(sem_svc, (kipc_perm_t *)sp);
        kmem_free(undo, size);
    }

    avl_destroy(tree);
    kmem_free(tree, sizeof (avl_tree_t));
}
Esempio n. 7
0
/*
 * ipc_send_code() -
 *
 *	Support function for ipc_send_term() and ipc_send_resume().
 */
static int
ipc_send_code(char *archive_dir, int code)
{
	struct {
		long	mtype;
		char	mtext[1];
	} msg;

	if (ipc_generate_keys(archive_dir) < 0)
		return -1;

	if ((semid = semget(semkey, 0, 0)) < 0)
	{
		if (!opt_quiet)
			fprintf(stderr, "no logshipper daemon running\n");
		return 2;
	}

	if (ipc_lock() < 0)
		return -1;

	if ((msgid = msgget(msgkey, 0)) < 0)
	{
		fprintf(stderr, "msgget() failed in ipc_send_code(): %s\n",
				strerror(errno));
		ipc_unlock();
		return -1;
	}
	
	msg.mtype = (long)code;
	if (msgsnd(msgid, &msg, 0, 0) < 0)
	{
		fprintf(stderr, "msgsnd() failed in ipc_send_code(): %s\n",
				strerror(errno));
		ipc_unlock();
		return -1;
	}

	return ipc_unlock();
}
Esempio n. 8
0
void GameFieldView::paintEvent(QPaintEvent *event) {
    Q_UNUSED(event);
    QPainter qp(this);
    qp.setRenderHint(QPainter::Antialiasing, true);
    
    std::unique_lock<std::mutex> ipc_lock(ipc.mutex);

    
    double field_size = std::min(width() - 2, height() - 2);
    double field_dx = 1 + (width() - 2 - field_size) / 2;
    double field_dy = 1 + (height() - 2 - field_size) / 2;
    double field_to_px_coef = field_size / ipc.current_field.radius;
    
    QRectF r = QRectF(field_dx, field_dy, field_size, field_size);

    QBrush fieldBrush(QColor(200, 150, 150));

    qp.setBrush(fieldBrush);
    qp.drawEllipse(r);

    {
        std::ostringstream fmt_stream;
        fmt_stream << "state: ";
        switch (ipc.connection_state) {
            case ab::ui::ConnectionState::connecting: fmt_stream << "connecting"; break;
            case ab::ui::ConnectionState::connected: fmt_stream << "connected"; break;
            case ab::ui::ConnectionState::disconnected: fmt_stream << "disconnected"; break;
            default: break;
        }
        fmt_stream << ", tick: " << ipc.field_counter;
        qp.drawText(QRect(0, 0, width(), height()), QString(fmt_stream.str().c_str()));
    }

    QBrush playerBrush(QColor(120, 150, 200));
    QPen velocity_pen(QColor(50, 200, 60));
    velocity_pen.setWidth(5);
    qp.setBrush(playerBrush);
    for (const ab::Player& player: ipc.current_field.players) {
        QRectF playerRect = QRectF(field_dx + (player.center.x - player.radius) * field_to_px_coef,
                                   field_dy + (player.center.y - player.radius) * field_to_px_coef,
                                   2 * player.radius * field_to_px_coef,
                                   2 * player.radius * field_to_px_coef);
        qp.drawEllipse(playerRect);
        qp.save();
        qp.setPen(velocity_pen);
        qp.drawLine(field_dx + player.center.x * field_to_px_coef,
                    field_dy + player.center.y * field_to_px_coef,
                    field_dx + (player.center.x + player.velocity.x) * field_to_px_coef,
                    field_dy + (player.center.y + player.velocity.y) * field_to_px_coef);
        qp.restore();
        {
            std::ostringstream fmt_stream;
            fmt_stream << player.id;
            qp.drawText(playerRect, Qt::AlignCenter, QString(fmt_stream.str().c_str()));
        }
    }

    QBrush coinBrush(QColor(220, 240, 150));
    qp.setBrush(coinBrush);
    for (const ab::Coin& coin: ipc.current_field.coins) {
        QRectF coinRect = QRectF(field_dx + (coin.center.x - coin.radius) * field_to_px_coef,
                                 field_dy + (coin.center.y - coin.radius) * field_to_px_coef,
                                 2 * coin.radius * field_to_px_coef,
                                 2 * coin.radius * field_to_px_coef);
        qp.drawEllipse(coinRect);
    }
}
Esempio n. 9
0
/*
 * ipc_init() -
 *
 *	Called to setup or connect to the semaphore set and message queue.
 */
int
ipc_init(char *archive_dir)
{
	struct sembuf	sops[2];

	if (ipc_generate_keys(archive_dir) < 0)
		return -1;

	/*
	 * We eventually have to start over again in case
	 * the existing daemon destroys the semaphore set
	 * after we attached and before we can lock it.
	 */
	while (true)
	{
		/*
		 * Create or attach to the semaphore set
		 */
		semid = semget(semkey, 3, 0700 | IPC_CREAT);
		if (semid < 0)
		{
			fprintf(stderr, "cannot create or attache to semaphore set\n"
							"semget(): %s\n", strerror(errno));
			return -1;
		}

		/*
		 * We now do two initial operations with NOWAIT:
		 *		wait for #1 =0
		 *		inc sem  #1 +1
		 * We never again touch semaphore #1, so this either succeeds, meaning
		 * that we created the set and hold the current lock. Or it fails with
		 * EAGAIN, meaning we attached to an existing set. Or it fails with
		 * EIDRM, meaning the set was destroyed.
		 */
		sops[0].sem_num = 1;
		sops[0].sem_op  = 0;
		sops[0].sem_flg = IPC_NOWAIT;
		sops[1].sem_num = 1;
		sops[1].sem_op  = 1;
		sops[1].sem_flg = 0;

		if (semop(semid, sops, 2) < 0)
		{
			if (errno == EIDRM)
				continue;

			if (errno != EAGAIN)
			{
				fprintf(stderr, "semop failed in ipc_init(): %s",
						strerror(errno));
				return -1;
			}

			/*
			 * Grab the lock on semaphore #0
			 */
			if (ipc_lock() < 0)
			{
				/*
				 * Since theres a gap between attaching and locking, the
				 * set could have been destroyed. In that case, start over.
				 */
				if (errno == EIDRM)
					continue;

				fprintf(stderr, "semop() failed in ipc_init(): %s\n",
						strerror(errno));
				return -1;
			}

			ipc_creator = 0;
		}
		else
		{
			/*
			 * Initial semop succeeded - we are the creator of this set.
			 */
			ipc_creator = 1;
			signal(SIGINT, ipc_sighandler);
			signal(SIGTERM, ipc_sighandler);
			signal(SIGPIPE, ipc_sighandler);
		}

		break;
	}

	/*
	 * At this point we have the semaphore set and it is locked.
	 */
	msgid = msgget(msgkey, 0700 | IPC_CREAT);
	if (msgid < 0)
	{
		fprintf(stderr, "msgget() failed in ipc_init(): %s\n", strerror(errno));
		if (ipc_creator)
		{
			if (semctl(semid, 0, IPC_RMID) < 0)
				fprintf(stderr, "semctl() failed in ipc_init(): %s\n",
						strerror(errno));
		}
		return -1;
	}

	return ipc_creator;
}
Esempio n. 10
0
struct sem_array *sem_lock(struct ipc_namespace *ns, int id)
{
	struct kern_ipc_perm *ipcp = ipc_lock(&sem_ids(ns), id);

	return container_of(ipcp, struct sem_array, sem_perm);
}