/*
 * Server-side change notification management
 *
 * Copyright (C) 1998 Alexandre Julliard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"
#include "wine/port.h"

#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/stat.h>

#include "windef.h"

#include "file.h"
#include "handle.h"
#include "thread.h"
#include "request.h"

#ifdef linux
#ifndef F_NOTIFY
#define F_NOTIFY 1026
#define DN_ACCESS       0x00000001      /* File accessed */
#define DN_MODIFY       0x00000002      /* File modified */
#define DN_CREATE       0x00000004      /* File created */
#define DN_DELETE       0x00000008      /* File removed */
#define DN_RENAME       0x00000010      /* File renamed */
#define DN_ATTRIB       0x00000020      /* File changed attibutes */
#define DN_MULTISHOT    0x80000000      /* Don't remove notifier */
#endif
#endif

struct change
{
    struct object  obj;      /* object header */
    struct fd     *fd;       /* file descriptor to the directory */
    struct list    entry;    /* entry in global change notifications list */
    int            subtree;  /* watch all the subtree */
    unsigned int   filter;   /* notification filter */
    int            notified; /* SIGIO counter */
    long           signaled; /* the file changed */
};

static void change_dump( struct object *obj, int verbose );
static int change_signaled( struct object *obj, struct thread *thread );
static void change_destroy( struct object *obj );

static const struct object_ops change_ops =
{
    sizeof(struct change),    /* size */
    change_dump,              /* dump */
    add_queue,                /* add_queue */
    remove_queue,             /* remove_queue */
    change_signaled,          /* signaled */
    no_satisfied,             /* satisfied */
    no_signal,                /* signal */
    no_get_fd,                /* get_fd */
    no_close_handle,          /* close_handle */
    change_destroy            /* destroy */
};

static struct list change_list = LIST_INIT(change_list);

static void adjust_changes( int fd, unsigned int filter )
{
#if defined(F_SETSIG) && defined(F_NOTIFY)
    unsigned int val;
    if ( 0 > fcntl( fd, F_SETSIG, SIGIO) )
        return;

    val = DN_MULTISHOT;
    if (filter & FILE_NOTIFY_CHANGE_FILE_NAME)
        val |= DN_RENAME | DN_DELETE | DN_CREATE;
    if (filter & FILE_NOTIFY_CHANGE_DIR_NAME)
        val |= DN_RENAME | DN_DELETE | DN_CREATE;
    if (filter & FILE_NOTIFY_CHANGE_ATTRIBUTES)
        val |= DN_ATTRIB;
    if (filter & FILE_NOTIFY_CHANGE_SIZE)
        val |= DN_MODIFY;
    if (filter & FILE_NOTIFY_CHANGE_LAST_WRITE)
        val |= DN_MODIFY;
    if (filter & FILE_NOTIFY_CHANGE_LAST_ACCESS)
        val |= DN_ACCESS;
    if (filter & FILE_NOTIFY_CHANGE_CREATION)
        val |= DN_CREATE;
    if (filter & FILE_NOTIFY_CHANGE_SECURITY)
        val |= DN_ATTRIB;
    fcntl( fd, F_NOTIFY, val );
#endif
}

/* insert change in the global list */
static inline void insert_change( struct change *change )
{
    sigset_t sigset;

    sigemptyset( &sigset );
    sigaddset( &sigset, SIGIO );
    sigprocmask( SIG_BLOCK, &sigset, NULL );
    list_add_head( &change_list, &change->entry );
    sigprocmask( SIG_UNBLOCK, &sigset, NULL );
}

/* remove change from the global list */
static inline void remove_change( struct change *change )
{
    sigset_t sigset;

    sigemptyset( &sigset );
    sigaddset( &sigset, SIGIO );
    sigprocmask( SIG_BLOCK, &sigset, NULL );
    list_remove( &change->entry );
    sigprocmask( SIG_UNBLOCK, &sigset, NULL );
}

static struct change *create_change_notification( struct fd *fd, int subtree, unsigned int filter )
{
    struct change *change;
    struct stat st;
    int unix_fd = get_unix_fd( fd );

    if (unix_fd == -1) return NULL;

    if (fstat( unix_fd, &st ) == -1 || !S_ISDIR(st.st_mode))
    {
        set_error( STATUS_NOT_A_DIRECTORY );
        return NULL;
    }

    if ((change = alloc_object( &change_ops )))
    {
        change->fd       = (struct fd *)grab_object( fd );
        change->subtree  = subtree;
        change->filter   = filter;
        change->notified = 0;
        change->signaled = 0;
        insert_change( change );
        adjust_changes( unix_fd, filter );
    }
    return change;
}

static void change_dump( struct object *obj, int verbose )
{
    struct change *change = (struct change *)obj;
    assert( obj->ops == &change_ops );
    fprintf( stderr, "Change notification fd=%p sub=%d filter=%08x\n",
             change->fd, change->subtree, change->filter );
}

static int change_signaled( struct object *obj, struct thread *thread )
{
    struct change *change = (struct change *)obj;

    return change->signaled != 0;
}

static void change_destroy( struct object *obj )
{
    struct change *change = (struct change *)obj;

    release_object( change->fd );
    remove_change( change );
}

/* enter here directly from SIGIO signal handler */
void do_change_notify( int unix_fd )
{
    struct list *ptr;

    /* FIXME: this is O(n) ... probably can be improved */
    LIST_FOR_EACH( ptr, &change_list )
    {
        struct change *change = LIST_ENTRY( ptr, struct change, entry );
        if (get_unix_fd( change->fd ) != unix_fd) continue;
        interlocked_xchg_add( &change->notified, 1 );
        break;
    }
}

/* SIGIO callback, called synchronously with the poll loop */
void sigio_callback(void)
{
    struct list *ptr;

    LIST_FOR_EACH( ptr, &change_list )
    {
        struct change *change = LIST_ENTRY( ptr, struct change, entry );
        long count = interlocked_xchg( &change->notified, 0 );
        if (count)
        {
            change->signaled += count;
            if (change->signaled == count)  /* was it 0? */
                wake_up( &change->obj, 0 );
        }
    }
}

/* create a change notification */
DECL_HANDLER(create_change_notification)
{
    struct change *change;
    struct file *file;
    struct fd *fd;

    if (!(file = get_file_obj( current->process, req->handle, 0 ))) return;
    fd = get_obj_fd( (struct object *)file );
    release_object( file );
    if (!fd) return;

    if ((change = create_change_notification( fd, req->subtree, req->filter )))
    {
        reply->handle = alloc_handle( current->process, change,
                                      STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE, 0 );
        release_object( change );
    }
    release_object( fd );
}

/* move to the next change notification */
DECL_HANDLER(next_change_notification)
{
    struct change *change;

    if ((change = (struct change *)get_handle_obj( current->process, req->handle,
                                                   0, &change_ops )))
    {
        if (change->signaled > 0) change->signaled--;
        release_object( change );
    }
}
