24 #define FUSE_USE_VERSION 31 
   43 static unsigned fsel_open_mask;
 
   44 static const char fsel_hex_map[] = 
"0123456789ABCDEF";
 
   45 static struct fuse *fsel_fuse;  
 
   47 #define FSEL_CNT_MAX    10       
   50 static pthread_mutex_t fsel_mutex;      
 
   51 static unsigned fsel_poll_notify_mask;  
 
   52 static struct fuse_pollhandle *fsel_poll_handle[FSEL_FILES]; 
 
   53 static unsigned fsel_cnt[FSEL_FILES];   
 
   55 static int fsel_path_index(
const char *path)
 
   59         if (strlen(path) != 2 || path[0] != 
'/' || !isxdigit(ch) || islower(ch))
 
   61         return ch <= 
'9' ? ch - 
'0' : ch - 
'A' + 10;
 
   64 static int fsel_getattr(
const char *path, 
struct stat *stbuf,
 
   70         memset(stbuf, 0, 
sizeof(
struct stat));
 
   72         if (strcmp(path, 
"/") == 0) {
 
   73                 stbuf->st_mode = S_IFDIR | 0555;
 
   78         idx = fsel_path_index(path);
 
   82         stbuf->st_mode = S_IFREG | 0444;
 
   84         stbuf->st_size = fsel_cnt[idx];
 
   88 static int fsel_readdir(
const char *path, 
void *buf, 
fuse_fill_dir_t filler,
 
   99         if (strcmp(path, 
"/") != 0)
 
  102         for (i = 0; i < FSEL_FILES; i++) {
 
  103                 name[0] = fsel_hex_map[i];
 
  104                 filler(buf, name, NULL, 0, 0);
 
  112         int idx = fsel_path_index(path);
 
  116         if ((fi->
flags & O_ACCMODE) != O_RDONLY)
 
  118         if (fsel_open_mask & (1 << idx))
 
  120         fsel_open_mask |= (1 << idx);
 
  134 static int fsel_release(
const char *path, 
struct fuse_file_info *fi)
 
  140         fsel_open_mask &= ~(1 << idx);
 
  144 static int fsel_read(
const char *path, 
char *buf, 
size_t size, off_t offset,
 
  152         pthread_mutex_lock(&fsel_mutex);
 
  153         if (fsel_cnt[idx] < size)
 
  154                 size = fsel_cnt[idx];
 
  155         printf(
"READ   %X transferred=%zu cnt=%u\n", idx, size, fsel_cnt[idx]);
 
  156         fsel_cnt[idx] -= size;
 
  157         pthread_mutex_unlock(&fsel_mutex);
 
  159         memset(buf, fsel_hex_map[idx], size);
 
  164                      struct fuse_pollhandle *ph, 
unsigned *reventsp)
 
  166         static unsigned polled_zero;
 
  180                         fsel_fuse = cxt->
fuse;
 
  183         pthread_mutex_lock(&fsel_mutex);
 
  186                 struct fuse_pollhandle *oldph = fsel_poll_handle[idx];
 
  191                 fsel_poll_notify_mask |= (1 << idx);
 
  192                 fsel_poll_handle[idx] = ph;
 
  197                 printf(
"POLL   %X cnt=%u polled_zero=%u\n",
 
  198                        idx, fsel_cnt[idx], polled_zero);
 
  203         pthread_mutex_unlock(&fsel_mutex);
 
  209         .readdir        = fsel_readdir,
 
  211         .release        = fsel_release,
 
  216 static void *fsel_producer(
void *data)
 
  218         const struct timespec interval = { 0, 250000000 };
 
  219         unsigned idx = 0, nr = 1;
 
  226                 pthread_mutex_lock(&fsel_mutex);
 
  234                 for (i = 0, t = idx; i < nr;
 
  235                      i++, t = (t + FSEL_FILES / nr) % FSEL_FILES) {
 
  236                         if (fsel_cnt[t] == FSEL_CNT_MAX)
 
  240                         if (fsel_fuse && (fsel_poll_notify_mask & (1 << t))) {
 
  241                                 struct fuse_pollhandle *ph;
 
  243                                 printf(
"NOTIFY %X\n", t);
 
  244                                 ph = fsel_poll_handle[t];
 
  245                                 fuse_notify_poll(ph);
 
  247                                 fsel_poll_notify_mask &= ~(1 << t);
 
  248                                 fsel_poll_handle[t] = NULL;
 
  252                 idx = (idx + 1) % FSEL_FILES;
 
  256                 pthread_mutex_unlock(&fsel_mutex);
 
  258                 nanosleep(&interval, NULL);
 
  264 int main(
int argc, 
char *argv[])
 
  270         errno = pthread_mutex_init(&fsel_mutex, NULL);
 
  272                 perror(
"pthread_mutex_init");
 
  276         errno = pthread_attr_init(&attr);
 
  278                 perror(
"pthread_attr_init");
 
  282         errno = pthread_create(&producer, &attr, fsel_producer, NULL);
 
  284                 perror(
"pthread_create");
 
  288         ret = 
fuse_main(argc, argv, &fsel_oper, NULL);
 
  290         pthread_cancel(producer);
 
  291         pthread_join(producer, NULL);
 
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
struct fuse_context * fuse_get_context(void)
#define fuse_main(argc, argv, op, private_data)
void fuse_pollhandle_destroy(struct fuse_pollhandle *ph)
int(* getattr)(const char *, struct stat *, struct fuse_file_info *fi)