* Initial import of the GtkAML gui frontend - Mostly implemented in just one night :)
* Import the squeue c and vapi sources * Make 0xFFFF run as squeue daemon with -Q flag * Up to 0.4
This commit is contained in:
1 parent
32a59f4279
commit
2ddb2923c6
11 files changed
+714
-7
No files matched your search
@@ -0,0 +1,250 @@
|
||||
#include "squeue.h"
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <signal.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define POOL_SIZE ITEM_MAX*ITEM_SIZE
|
||||
#define ITEM_SIZE 80
|
||||
#define ITEM_MAX 10
|
||||
|
||||
int squeue_release(const char *file)
|
||||
{
|
||||
int shmid;
|
||||
key_t k = ftok(file, 0xa3);
|
||||
|
||||
if (k == -1) {
|
||||
perror("ftok");
|
||||
return -1;
|
||||
}
|
||||
|
||||
shmid = shmget(k, POOL_SIZE, 0666);
|
||||
if (shmid == -1)
|
||||
return -1; // not released
|
||||
return shmctl(shmid, IPC_RMID,NULL);
|
||||
}
|
||||
|
||||
struct squeue_t *squeue_open(const char *file, int mode)
|
||||
{
|
||||
struct squeue_t *q;
|
||||
char *pool;
|
||||
int shmid;
|
||||
key_t k = ftok(file, 0xa3);
|
||||
_retry:
|
||||
shmid = shmget(k, POOL_SIZE, 0666);
|
||||
if (shmid == -1) {
|
||||
if (mode == Q_WAIT) {
|
||||
usleep(200);
|
||||
goto _retry;
|
||||
}
|
||||
shmid = shmget(k, POOL_SIZE, 0666|IPC_EXCL|((mode==Q_CREAT)?IPC_CREAT:0));
|
||||
if (shmid == -1) {
|
||||
if (mode == Q_WAIT) {
|
||||
usleep(200);
|
||||
goto _retry;
|
||||
}
|
||||
perror("shmget");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == Q_WAIT)
|
||||
mode = Q_OPEN;
|
||||
|
||||
pool = shmat(shmid, NULL, k);
|
||||
if (((int)pool) == -1) {
|
||||
perror("shmat\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mode == Q_CREAT)
|
||||
memset(pool, '\0', POOL_SIZE);
|
||||
|
||||
q = (struct squeue_t *)malloc(sizeof(struct squeue_t));
|
||||
memset(q, '\0', sizeof(struct squeue_t));
|
||||
q->shmid = shmid;
|
||||
q->pool = pool;
|
||||
q->mode = mode;
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
void squeue_free(struct squeue_t *q)
|
||||
{
|
||||
free(q);
|
||||
}
|
||||
|
||||
int squeue_close(struct squeue_t *q)
|
||||
{
|
||||
char *pool;
|
||||
|
||||
if (q==NULL)
|
||||
return -1;
|
||||
|
||||
pool = q->pool;
|
||||
shmctl(q->shmid, IPC_RMID, NULL);
|
||||
free(q);
|
||||
return shmdt(pool);
|
||||
}
|
||||
|
||||
int squeue_push(struct squeue_t *q, const char *str, int lock)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (q==NULL)
|
||||
return -1;
|
||||
// if (q->mode == Q_CREAT) {
|
||||
// printf("squeue_push: cannot push from the creator\n");
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
if (str==NULL||strlen(str)>ITEM_SIZE)
|
||||
return -1;
|
||||
do {
|
||||
if (q->squeue_idx >= ITEM_MAX) {
|
||||
while (q->pool[0]!='\0') {
|
||||
q->squeue_locks++;
|
||||
if (!lock) {
|
||||
printf("buffer is full\n");
|
||||
return -1;
|
||||
}
|
||||
usleep(200);
|
||||
}
|
||||
q->squeue_idx = 0;
|
||||
}
|
||||
|
||||
for(i=q->squeue_idx*ITEM_SIZE;i<POOL_SIZE;i+=ITEM_SIZE) {
|
||||
if (q->pool[i]=='\0') {
|
||||
strcpy(q->pool+i, str);
|
||||
q->squeue_idx++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
q->squeue_locks++;
|
||||
} while (lock);
|
||||
q->squeue_lost++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int squeue_pop(struct squeue_t *q)
|
||||
{
|
||||
int i;
|
||||
int two = 1;
|
||||
|
||||
if (q==NULL)
|
||||
return -1;
|
||||
// if (q->mode == Q_OPEN) { // cannot pop when not owner of squeue
|
||||
// fprintf(stderr, "squeue_pop: cannot pop when you are not owner.\n");
|
||||
// return -1;
|
||||
// }
|
||||
for(two=1;two--;q->head_idx = 0)
|
||||
for(i=q->head_idx*ITEM_SIZE;i<POOL_SIZE;i+=ITEM_SIZE) {
|
||||
if (q->pool[i]!='\0') {
|
||||
q->pool[i]='\0';
|
||||
q->head_idx++;
|
||||
q->squeue_pops++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
q->squeue_oops++;
|
||||
fprintf(stderr, "WARNING: race condition detected in squeue.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *squeue_get(struct squeue_t *q, int lock)
|
||||
{
|
||||
int i=0;
|
||||
int two = 1;
|
||||
|
||||
if(q==NULL)
|
||||
return NULL;
|
||||
// if (q->mode == Q_OPEN) { // cannot pop when not owner of squeue
|
||||
// fprintf(stderr, "squeue_get: cannot pop when you are not owner.\n");
|
||||
// return NULL;
|
||||
// }
|
||||
do {
|
||||
for(two=1;two--;q->head_idx = 0) {
|
||||
for(i=q->head_idx*ITEM_SIZE;i<POOL_SIZE;i+=ITEM_SIZE)
|
||||
if (q->pool[i]!='\0')
|
||||
return q->pool+i;
|
||||
}
|
||||
if (lock)
|
||||
usleep(500);
|
||||
} while (lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void squeue_stats(struct squeue_t *q)
|
||||
{
|
||||
if(q==NULL)
|
||||
return;
|
||||
printf("Queue locks: %d\n", q->squeue_locks);
|
||||
printf("Queue lost: %d\n", q->squeue_lost);
|
||||
printf("Queue oops: %d\n", q->squeue_oops);
|
||||
printf("Queue pops: %d\n", q->squeue_pops);
|
||||
}
|
||||
|
||||
#if _MAIN_
|
||||
struct squeue_t *q;
|
||||
|
||||
int sigc()
|
||||
{
|
||||
squeue_stats(q);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
char buf[102];
|
||||
int i;
|
||||
int pid;
|
||||
|
||||
signal(SIGINT, sigc);
|
||||
|
||||
squeue_release("/dev/null");
|
||||
|
||||
pid = fork();
|
||||
if (pid) {
|
||||
q = squeue_open("/dev/null", Q_CREAT);
|
||||
if (q == NULL) {
|
||||
perror("oops");
|
||||
kill(pid, SIGINT);
|
||||
return;
|
||||
}
|
||||
squeue_push(q, "Hello World", 0);
|
||||
squeue_push(q, "jeje msg 2", 0);
|
||||
|
||||
while(1) {
|
||||
char *uh = squeue_get(q,1);
|
||||
if (uh) {
|
||||
printf("get: (%s)\n", uh);
|
||||
squeue_pop(q);
|
||||
}
|
||||
usleep(200);
|
||||
}
|
||||
squeue_close(q);
|
||||
} else {
|
||||
q = squeue_open("/dev/null", Q_WAIT);
|
||||
if (q == NULL) {
|
||||
perror("oops");
|
||||
return;
|
||||
}
|
||||
for(i=0;i<128;i++) {
|
||||
sprintf(buf, "puta%d", i);
|
||||
squeue_push(q, buf, 1);
|
||||
usleep(100);
|
||||
}
|
||||
squeue_stats(q);
|
||||
printf("cya\n");
|
||||
squeue_close(q);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,27 @@
|
||||
struct squeue_t {
|
||||
int shmid;
|
||||
int mode;
|
||||
char *pool;
|
||||
/* pointers */
|
||||
int head_idx;
|
||||
int squeue_idx;
|
||||
/* counters */
|
||||
int squeue_locks;
|
||||
int squeue_lost;
|
||||
int squeue_oops;
|
||||
int squeue_pops;
|
||||
};
|
||||
|
||||
|
||||
#define Q_OPEN 0
|
||||
#define Q_CREAT 1
|
||||
#define Q_WAIT 2
|
||||
|
||||
int squeue_release(const char *file);
|
||||
struct squeue_t *squeue_open(const char *file, int init);
|
||||
int squeue_close(struct squeue_t *q);
|
||||
void squeue_free(struct squeue_t *q);
|
||||
int squeue_push(struct squeue_t *q, const char *str, int lock);
|
||||
int squeue_pop(struct squeue_t *q);
|
||||
char *squeue_get(struct squeue_t *q, int lock);
|
||||
void squeue_stats(struct squeue_t *q);
|
||||
@@ -0,0 +1,43 @@
|
||||
using GLib;
|
||||
|
||||
[CCode (lower_case_cprefix = "squeue_", cheader_filename = "squeue.h")]
|
||||
namespace SQueues {
|
||||
[CCode (cname = "struct squeue_t", free_function = "squeue_free")]
|
||||
public struct SQueue {
|
||||
int shmid;
|
||||
int mode;
|
||||
char *pool;
|
||||
/* pointers */
|
||||
int head_idx;
|
||||
int queue_idx;
|
||||
/* counters */
|
||||
int locks;
|
||||
int lost;
|
||||
int oops;
|
||||
int pops;
|
||||
[CCode (cname = "squeue_open")]
|
||||
public static SQueue* open(string file, int mode);
|
||||
[CCode (cname = "squeue_push")]
|
||||
public int push(string msg, int l);
|
||||
[CCode (cname = "squeue_get")]
|
||||
public weak string get(int l);
|
||||
[CCode (cname = "squeue_pop")]
|
||||
public int pop();
|
||||
[CCode (cname = "squeue_stats")]
|
||||
public int stats();
|
||||
[CCode (cname = "squeue_close")]
|
||||
public int close();
|
||||
[CCode (cname = "squeue_free")]
|
||||
public int free();
|
||||
[CCode (cname = "squeue_release")]
|
||||
public static int release(string file);
|
||||
|
||||
}
|
||||
|
||||
[CCode (cprefix = "Q_", cheader_fileneme = "squeue.h")]
|
||||
public enum SQueueMode {
|
||||
OPEN = 0,
|
||||
CREAT = 1,
|
||||
WAIT = 2
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user