static void locking_slave(int in_fd, int out_fd) { char cmd; int rv; file_lock *lock = file_lock_new(TEST_FILENAME); gboolean locked = 0; while (1) { if (!pipeget(in_fd, &cmd)) cmd = 'q'; switch (cmd) { case 'q': /* q = quit */ tu_dbg("slave: quitting\n"); file_lock_free(lock); lock = NULL; return; case 'l': /* l = try locking; reply with 'y' or 'n' */ g_assert(!locked); rv = file_lock_lock(lock); if (rv == -1) { g_fprintf(stderr, "file_lock_lock: %s\n", strerror(errno)); return; } tu_dbg("slave: lock attempt => %s\n", (rv == 1)? "n" : "y"); pipeput(out_fd, (rv == 1)? "n" : "y"); if (rv != 1) locked = 1; break; case 'i': /* i = increment counter, reply with new value */ g_assert(locked); if (!inc_counter(lock)) return; tu_dbg("slave: inc'd to %c\n", lock->data[0]); pipeput(out_fd, lock->data); break; case 'u': /* u = try unlocking; reply with 'k' */ g_assert(locked); rv = file_lock_unlock(lock); if (rv != 0) { g_fprintf(stderr, "file_lock_unlock: %s\n", strerror(errno)); return; } tu_dbg("slave: unlocked\n"); pipeput(out_fd, "k"); locked = 0; break; default: return; } } }
void piperecvtask(void) { int getsize; unsigned int gettime; int getcount; int pipe; int prio; GetInfo getinfo; /* matching (ALL_N) */ for (getsize = 8; getsize <= MESSAGE_SIZE_PIPE; getsize <<= 1) { for (pipe = 0; pipe < 3; pipe++) { getcount = NR_OF_PIPE_RUNS; pipeget(TestPipes[pipe], _ALL_N, getsize, getcount, &gettime); getinfo.time = gettime; getinfo.size = getsize; getinfo.count = getcount; task_fifo_put_wait(CH_COMM, &getinfo); /* acknowledge to master */ } } for (prio = 0; prio < 2; prio++) { /* non-matching (1_TO_N) */ for (getsize = (MESSAGE_SIZE_PIPE); getsize >= 8; getsize >>= 1) { getcount = MESSAGE_SIZE_PIPE / getsize; for (pipe = 0; pipe < 3; pipe++) { /* size*count == MESSAGE_SIZE_PIPE */ pipeget(TestPipes[pipe], _1_TO_N, getsize, getcount, &gettime); getinfo.time = gettime; getinfo.size = getsize; getinfo.count = getcount; task_fifo_put_wait(CH_COMM, &getinfo); /* acknowledge to master */ } } } }
static int locking_master(int in_fd, int out_fd) { file_lock *lock = file_lock_new(TEST_FILENAME); int rv; char slaveres; /* start by locking here and incrementing the value */ rv = file_lock_lock(lock); if (rv == -1) { g_fprintf(stderr, "file_lock_lock: %s\n", strerror(errno)); return 0; } g_assert(rv != 1); /* not already locked */ tu_dbg("master: locked\n"); if (!inc_counter(lock)) return 0; g_assert(lock->data[0] == 'b'); tu_dbg("master: inc'd to b\n"); /* unlock and re-lock */ rv = file_lock_unlock(lock); if (rv != 0) { g_fprintf(stderr, "file_lock_unlock: %s\n", strerror(errno)); return 0; } tu_dbg("master: unlocked\n"); rv = file_lock_lock(lock); if (rv == -1) { g_fprintf(stderr, "file_lock_lock: %s\n", strerror(errno)); return 0; } g_assert(rv != 1); /* not already locked */ tu_dbg("master: locked\n"); /* inc it again */ g_assert(lock->data[0] == 'b'); inc_counter(lock); g_assert(lock->data[0] == 'c'); tu_dbg("master: inc'd to c\n"); /* the slave should fail to get a lock now */ pipeput(out_fd, "l"); g_assert(pipeget(in_fd, &slaveres)); g_assert(slaveres == 'n'); /* and, finally unlock */ rv = file_lock_unlock(lock); if (rv != 0) { g_fprintf(stderr, "file_lock_unlock: %s\n", strerror(errno)); return 0; } tu_dbg("master: unlocked\n"); /* the slave should succeed now */ pipeput(out_fd, "l"); g_assert(pipeget(in_fd, &slaveres)); g_assert(slaveres == 'y'); pipeput(out_fd, "i"); g_assert(pipeget(in_fd, &slaveres)); g_assert(slaveres == 'd'); /* master shouldn't be able to lock now */ rv = file_lock_lock(lock); if (rv == -1) { g_fprintf(stderr, "file_lock_lock: %s\n", strerror(errno)); return 0; } g_assert(rv == 1); /* already locked */ tu_dbg("master: lock attempt failed (as expected)\n"); pipeput(out_fd, "i"); g_assert(pipeget(in_fd, &slaveres)); g_assert(slaveres == 'e'); /* get the slave to unlock */ pipeput(out_fd, "u"); g_assert(pipeget(in_fd, &slaveres)); g_assert(slaveres == 'k'); /* we should get a lock now */ rv = file_lock_lock(lock); if (rv == -1) { g_fprintf(stderr, "file_lock_lock: %s\n", strerror(errno)); return 0; } g_assert(rv != 1); /* not already locked */ tu_dbg("master: lock attempt succeeded\n"); g_assert(lock->data[0] == 'e'); /* leave it unlocked, just to see what happens */ return 1; }