diff --git a/headers/private/kernel/disk_device_manager/KDiskDeviceJob.h b/headers/private/kernel/disk_device_manager/KDiskDeviceJob.h index fdeddc21ef..8c17902657 100644 --- a/headers/private/kernel/disk_device_manager/KDiskDeviceJob.h +++ b/headers/private/kernel/disk_device_manager/KDiskDeviceJob.h @@ -10,43 +10,68 @@ struct user_disk_device_job_info; namespace BPrivate { namespace DiskDevice { +class KDiskDeviceJobQueue; + class KDiskDeviceJob { public: - KDiskDeviceJob(partition_id partition, partition_id scope = -1); + KDiskDeviceJob(uint32 type, partition_id partitionID, + partition_id scopeID = -1); virtual ~KDiskDeviceJob(); disk_job_id ID() const; + void SetJobQueue(KDiskDeviceJobQueue *queue); + KDiskDeviceJobQueue *JobQueue() const; + + uint32 Type() const; + void SetStatus(uint32 status); uint32 Status() const; - void SetDescription(const char *description); + status_t SetDescription(const char *description); const char *Description() const; - // Maybe better just a virtual void GetDescription(char*)? - void SetPartitionID(partition_id partitionID); - // Probably not needed, since passed to the constructor. partition_id PartitionID() const; partition_id ScopeID() const; - virtual void UpdateProgress(float progress); + void SetTaskCount(int32 count); + int32 TaskCount() const; + + void SetCompletedTasks(int32 count); + int32 CompletedTasks() const; + + void SetInterruptProperties(uint32 properties); + uint32 InterruptProperties() const; + + virtual void GetTaskDescription(char *description); + + void UpdateProgress(float progress); // may trigger a notification - // virtual, since some jobs are composed of several tasks (e.g. Move). - // We might want to explicitly support subtasks in the base class, or - // even in the userland API. void UpdateExtraProgress(const char *info); // triggers a notification float Progress() const; status_t GetInfo(user_disk_device_job_info *info); + status_t GetProgressInfo(disk_device_job_progress_info *info); - virtual status_t Do(); + virtual status_t Do() = 0; - // TODO: Do we want to add a Cancel() here? We probably can't tell the - // disk system directly anyway. That is, if the job is in progress, - // the disk system would have to check the job status periodically - // to find out, if the job had been canceled. But then a - // SetStatus(B_DISK_DEVICE_JOB_CANCELED) would be sufficient. +private: + static disk_job_id _NextID(); + + disk_job_id fID; + KDiskDeviceJobQueue *fJobQueue; + uint32 fType; + uint32 fStatus; + partition_id fPartitionID; + partition_id fScopeID; + char *fDescription; + int32 fTaskCount; + int32 fCompletedTasks; + uint32 fInterruptProperties; + float fProgress; + + static disk_job_id fNextID; }; } // namespace DiskDevice diff --git a/src/kernel/core/disk_device_manager/KDiskDeviceJob.cpp b/src/kernel/core/disk_device_manager/KDiskDeviceJob.cpp index a985d0edb6..e26c709995 100644 --- a/src/kernel/core/disk_device_manager/KDiskDeviceJob.cpp +++ b/src/kernel/core/disk_device_manager/KDiskDeviceJob.cpp @@ -1,3 +1,222 @@ // KDiskDeviceJob.cpp +#include "ddm_userland_interface.h" + #include "KDiskDeviceJob.h" +#include "KDiskDeviceUtils.h" + +// constructor +KDiskDeviceJob::KDiskDeviceJob(uint32 type, partition_id partitionID, + partition_id scopeID) + : fID(_NextID()), + fJobQueue(NULL), + fType(type), + fStatus(B_DISK_DEVICE_JOB_UNINITIALIZED), + fPartitionID(partitionID), + fScopeID(scopeID), + fDescription(NULL), + fTaskCount(1), + fCompletedTasks(0), + fInterruptProperties(0), + fProgress(0) +{ + if (fScopeID < 0) + fScopeID = fPartitionID; +} + +// destructor +KDiskDeviceJob::~KDiskDeviceJob() +{ + if (fDescription) + free(fDescription); +} + +// ID +disk_job_id +KDiskDeviceJob::ID() const +{ + return fID; +} + +// SetJobQueue +void +KDiskDeviceJob::SetJobQueue(KDiskDeviceJobQueue *queue) +{ + fJobQueue = queue; +} + +// JobQueue +BPrivate::DiskDevice::KDiskDeviceJobQueue * +KDiskDeviceJob::JobQueue() const +{ + return fJobQueue; +} + +// Type +uint32 +KDiskDeviceJob::Type() const +{ + return fType; +} + +// SetStatus +void +KDiskDeviceJob::SetStatus(uint32 status) +{ + fStatus = status; +} + +// Status +uint32 +KDiskDeviceJob::Status() const +{ + return fStatus; +} + +// SetDescription +status_t +KDiskDeviceJob::SetDescription(const char *description) +{ + return set_string(fDescription, description); +} + +// Description +const char * +KDiskDeviceJob::Description() const +{ + return fDescription; +} + +// PartitionID +partition_id +KDiskDeviceJob::PartitionID() const +{ + return fPartitionID; +} + +// ScopeID +partition_id +KDiskDeviceJob::ScopeID() const +{ + return fScopeID; +} + +// SetTaskCount +void +KDiskDeviceJob::SetTaskCount(int32 count) +{ + fTaskCount = count; +} + +// TaskCount +int32 +KDiskDeviceJob::TaskCount() const +{ + return fTaskCount; +} + +// SetCompletedTasks +void +KDiskDeviceJob::SetCompletedTasks(int32 count) +{ + fCompletedTasks = count; +} + +// CompletedTasks +int32 +KDiskDeviceJob::CompletedTasks() const +{ + return fCompletedTasks; +} + +// SetInterruptProperties +void +KDiskDeviceJob::SetInterruptProperties(uint32 properties) +{ + fInterruptProperties = properties; +} + +// InterruptProperties +uint32 +KDiskDeviceJob::InterruptProperties() const +{ + return fInterruptProperties; +} + +// GetTaskDescription +void +KDiskDeviceJob::GetTaskDescription(char *description) +{ + if (!description) + return; + if (fDescription) + strcpy(description, fDescription); + else + description[0] = '\0'; +} + +// UpdateProgress +void +KDiskDeviceJob::UpdateProgress(float progress) +{ + if (fProgress == progress) + return; + fProgress = progress; + // TODO: notification +} + +// UpdateExtraProgress +void +KDiskDeviceJob::UpdateExtraProgress(const char *info) +{ + // TODO:... +} + +// Progress +float +KDiskDeviceJob::Progress() const +{ + return fProgress; +} + +// GetInfo +status_t +KDiskDeviceJob::GetInfo(user_disk_device_job_info *info) +{ + if (!info) + return B_BAD_VALUE; + info->id = ID(); + info->type = Type(); + info->partition = PartitionID(); + if (Description()) + strcpy(info->description, Description()); + else + info->description[0] = '\0'; + return B_OK; +} + +// GetProgressInfo +status_t +KDiskDeviceJob::GetProgressInfo(disk_device_job_progress_info *info) +{ + if (!info) + return B_BAD_VALUE; + info->status = Status(); + info->interrupt_properties = InterruptProperties(); + info->task_count = TaskCount(); + info->completed_tasks = CompletedTasks(); + info->current_task_progress = Progress(); + GetTaskDescription(info->current_task_description); + return B_OK; +} + +// _NextID +disk_job_id +KDiskDeviceJob::_NextID() +{ + return atomic_add(&fNextID, 1); +} + +// fNextID +disk_job_id KDiskDeviceJob::fNextID = 0; +